仙人掌DP,套路还是1023的套路,dp式也还是比较水,f[i][0]表示i的子仙人掌的最大独立集,i不选,f[i][1]表示i的子仙人掌的最大独立集,i选,做环的时候强制令第一个点选或不选做两次
不过交到1040WA了是什么情况
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<iomanip> #include<cmath> #include<cstring> #include<ctime> #include<vector> #include<stack> #include<queue> #include<set> #include<bitset> #include<map> using namespace std; #define MAXN 50010 #define MAXM 120000 #define INF 1000000000 #define MOD 1000000007 #define ll long long #define eps 1e-8 struct vec{ int to; int fro; }; vec mp[MAXM]; int tai[MAXN],cnt; int dfn[MAXN],low[MAXN],tim; int fa[MAXN]; int dep[MAXN]; int f[MAXN][2]; int a[MAXN][4]; int n,m; void dp(int rt,int ed){ int i,k; a[1][0]=f[ed][0]; a[1][1]=-INF; a[1][2]=-INF; a[1][3]=f[ed][1]; for(k=fa[ed],i=2;k!=fa[rt];k=fa[k],i++){ a[i][0]=f[k][0]+max(a[i-1][0],a[i-1][1]); a[i][1]=f[k][1]+a[i-1][0]; a[i][2]=f[k][0]+max(a[i-1][2],a[i-1][3]); a[i][3]=f[k][1]+a[i-1][2]; } f[rt][0]=max(f[rt][0],max(a[i-1][0],a[i-1][2])); f[rt][1]=max(f[rt][1],a[i-1][1]); } void dfs(int x){ int i,y; dfn[x]=low[x]=++tim; dep[x]=dep[fa[x]]+1; f[x][1]=1; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(y==fa[x]){ continue ; } if(!dfn[y]){ fa[y]=x; dfs(y); } low[x]=min(low[x],low[y]); if(low[y]>dfn[x]){ f[x][1]+=f[y][0]; f[x][0]+=max(f[y][0],f[y][1]); } } for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(fa[y]!=x&&dfn[y]>dfn[x]){ dp(x,y); } } } inline void be(int x,int y){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; } inline void bde(int x,int y){ be(x,y); be(y,x); } int main(){ int i,j,x,y; scanf("%d%d",&n,&m); for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); bde(x,y); } dfs(1); printf("%d\n",max(f[1][0],f[1][1])); return 0; } /* */