Face questions
https://www.luogu.org/problemnew/show/P4410
Meaning of the questions: ask the cactus maximum independent set.
- $ Orzyyb $ $ tarjan $ $ dp $ in the way of thinking is a really wonderful.
- At the same time deal with two arrays, reducing the complexity of thinking (I wrote the code I jo there is always an aesthetic violence).
- $ G [x] [0/1] $ represent subtrees $ x $ and $ x $, if x is selected, the largest independent set is.
- $ F [x] [0/1] [0/1] $ meaningful if and only if $ $ X on the ring, and not for the first ring. $ X $ is provided as a ring head, $ T $ tail ring, $ f [y] [0/1] [0/1] $ $ Y represents a selected or not selected $, $ T $ not selected or selected, $ y $ and $ y $ sub-tree of the largest independent set is.
- Then transferred on it, pay attention to discounting the effect of previously transferred $ t $ in $ y $ in.
// luogu-judger-enable-o2 #include<cstdio> #include<cstring> #include<iostream> #include<stack> #include<vector> #define INF 1000000007 #define ri register int #define N 100500 using namespace std; int n,tn,m; int cir[N]; int a[N]; int ans; inline int read() { int ret=0,f=0; char ch=getchar(); while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') ret*=10,ret+=ch-'0',ch=getchar(); return f?-ret:ret; } struct graph { vector<int> to[N]; int dfn[N],low[N],cnt; stack<int> s; int f[N][2][2],g[N][2]; // state:t state:x void add_edge(int a,int b) { to[a].push_back(b); to[b].push_back(a); } void tarjan(int x) { dfn[x]=low[x]=++cnt; s.push(x); g[x][1]=a[x]; g[x][0]=0; for (ri i=0;i<to[x].size();i++) { int y=to[x][i]; if (dfn[y]) low[x]=min(low[x],dfn[y]); else { tarjan(y); low[x]=min(low[x],low[y]); if (low[y]>=dfn[x]) { int t=s.top(); if (t==y) { g[x][1]+=max(g[y][0],0); g[x][0]+=max(max(g[y][1],g[y][0]),0); continue; } int pret=t; s.pop(); f[t][1][1]=g[t][1]; f[t][0][0]=g[t][0]; f[t][1][0]=f[t][0][1]=-INF; do { t=s.top(); s.pop(); f[t][1][0]=g[t][1]-max(g[pret][0],0)+max(f[pret][0][0],0); f[t][0][0]=g[t][0]-max(max(g[pret][0],g[pret][1]),0)+max(max(f[pret][0][0],f[pret][1][0]),0); f[t][1][1]=g[t][1]-max(g[pret][0],0)+max(f[pret][0][1],0); f[t][0][1]=g[t][0]-max(max(g[pret][0],g[pret][1]),0)+max(max(f[pret][0][1],f[pret][1][1]),0); pret=t; } while (t!=y); g[x][1]+=max(f[y][0][0],0); g[x][0]+=max(max(max(f[y][0][0],f[y][0][1]),max(f[y][1][0],f[y][1][1])),0); } else { g[x][1]+=max(g[y][0],0); g[x][0]+=max(max(g[y][1],g[y][0]),0); } } } } } G; int main() { tn=n=read(); m=read(); for (ri i=1;i<=m;i++) { int u=read(),v=read(); G.add_edge(u,v); } for (ri i=1;i<=n;i++) a[i]=read(); G.cnt=0; G.tarjan(1); int ans=0; for (ri i=1;i<=n;i++) ans=max(ans,max(G.g[i][0],G.g[i][1])); printf("%d\n",ans); }