很裸的仙人掌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;
}