Luogu-4410 [HNOI2009]無歸島
阿新 • • 發佈:2018-11-04
裸的仙人掌最大獨立子集,結果一個zz的錯誤讓我調了好久...
\(-inf\)開始設為\(0x7fffffff\)結果\(A_i\)有負數一加就炸了
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=2e5+100,maxm=5e5+100,inf=200000000; int n,m,v[maxm],nex[maxm],head[maxn],num=1,f[maxn][2],a,b,tim,dfn[maxn],fa[maxn],p[maxn]; void add(int x,int y){ v[++num]=y; nex[num]=head[x]; head[x]=num; v[++num]=x; nex[num]=head[y]; head[y]=num; } void dp(int x,int y){ int z=y; int u0=0,u1=0,v0,v1; while(z!=x){ v1=u0+f[z][1],v0=u1+f[z][0];//交叉選擇 u0=v0,u1=max(v0,v1);//可以不選 z=fa[z]; } f[x][0]+=u1; u0=-inf,u1=0,z=y;//因為這是環,若x選了,則y不能選 while(z!=x){ v1=u0+f[z][1],v0=u1+f[z][0]; u0=v0,u1=max(v0,v1); z=fa[z]; } f[x][1]+=u0;//最後一個也不能選 } void tarjan(int x){ dfn[x]=++tim; for(int i=head[x];i;i=nex[i]) if(!dfn[v[i]]) fa[v[i]]=x,tarjan(v[i]); f[x][1]=p[x]; for(int i=head[x];i;i=nex[i]) if(dfn[v[i]]>dfn[x]&&fa[v[i]]!=x) dp(x,v[i]);//環內dp } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d",&a,&b),add(a,b); for(int i=1;i<=n;i++) scanf("%d",&p[i]); tarjan(1); printf("%d\n",max(f[1][0],f[1][1])); return 0; }