BZOJ4316: 小C的独立集

很裸的仙人掌DP (奇怪的是没有人来做

这是第一次独自打仙人掌DP

打的时候可能因为思路比较清晰 然后只有一个low打错了

然后需要说的是po姐貌似程序有问题。。我的一个小数据他就坏了。。

9 9
2 3
3 4
4 2
5 6
6 3
7 8
8 2
9 2
1 3


就是这个。。。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

struct Chain
{
  Chain *next;
  int u;
 Chain(){ next=NULL; }
}*Head[100001];

inline void addside(int a,int b)
{
	Chain *tp=new Chain;
	tp->u=b;
	tp->next=Head[a];
	Head[a]=tp;
}

int F[100001][3];
int Out_Cir[100001][3];
int Stack[100001];
int low[100001],f[100001],deep[100001],now[100001];
int cnt;

int f_DP[100001][3];
inline void DP(int root,int low)
{
    int n=1;
	Stack[0]=root;
	Stack[1]=low;
	while(true)
	{
		if(Stack[n]==root)break;
		Stack[n+1]=f[Stack[n++]];
	}
	//root buqu
	int Old[3]; 
	 f_DP[0][0]=f_DP[0][1]=0;
	 for(int i=1;i<=n;i++)
	     f_DP[i][1]=f_DP[i-1][0]+Out_Cir[Stack[i]][1],
	     f_DP[i][0]=max(f_DP[i-1][0],f_DP[i-1][1])+Out_Cir[Stack[i]][0];
	 Old[0]=f_DP[n][0];
	 //qu
	 f_DP[0][0]=-(1<<29);      
	 for(int i=1;i<=n;i++)
	     f_DP[i][1]=f_DP[i-1][0]+Out_Cir[Stack[i]][1],
	     f_DP[i][0]=max(f_DP[i-1][0],f_DP[i-1][1])+Out_Cir[Stack[i]][0];
	Old[1]=f_DP[n][1];
    Out_Cir[root][1]=Old[1];
    Out_Cir[root][0]=Old[0];
}




void DFS(int u)
{
	low[u]=now[u]=++cnt;
    Out_Cir[u][1]=1;
	Out_Cir[u][0]=0;
		if(u==28)
	 u++,u--;	
	for(Chain *tp=Head[u];tp;tp=tp->next)
	  if(tp->u!=f[u])
	     {
	     	if(deep[tp->u])
	     	  low[u]=min(low[u],now[tp->u]);
	     	else
	     	   {
	     	   	f[tp->u]=u;
	     	   	deep[tp->u]=deep[u]+1;
	     	   	DFS(tp->u);
	     	   	if(low[tp->u]>now[u]) 
	     	   	Out_Cir[u][1]+=Out_Cir[tp->u][0],
	     	   	Out_Cir[u][0]+=max(Out_Cir[tp->u][1],Out_Cir[tp->u][0]);
				low[u]=min(low[u],low[tp->u]);
	     	   }
	     }
	if(u==17)
	 u++,u--;
	for(Chain *tp=Head[u];tp;tp=tp->next)
	   if(tp->u!=f[u]&&low[tp->u]==now[u]&&deep[tp->u]!=deep[u]+1)
	      DP(u,tp->u);
}
char c;
inline void read(int &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int main()
{
	int n,m;
	read(n),read(m);
	while(m--)
	  {
	  	int i,j;
	  	read(i),read(j);
	  	addside(i,j);
	  	addside(j,i);
	  }
	deep[1]=1;
	f[1]=1;
	DFS(1);
	printf("%d\n",max(Out_Cir[1][0],Out_Cir[1][1]));
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值