BZOJ1040 [ZJOI2008]骑士[基环树DP]
实际上就是一般基环树DP套路性做法,断环成树,见过一题就知道了,具体可以看上一篇。这题基本一致。。。也是考虑断开后两点的影响关系分两种讨论。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define mst(x) memset(x,0,sizeof x) 8 #define dbg(x) cerr << #x << " = " << x <<endl 9 #define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl 10 using namespace std; 11 typedef long long ll; 12 typedef double db; 13 typedef pair<int,int> pii; 14 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 15 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 16 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 17 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 18 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 19 template<typename T>inline T read(T&x){ 20 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 21 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 22 } 23 const int N=1e6+7; 24 struct thxorz{ 25 int head[N],nxt[N<<1],to[N<<1],tot; 26 thxorz(){tot=1;} 27 inline void add(int x,int y){ 28 to[++tot]=y,nxt[tot]=head[x],head[x]=tot; 29 to[++tot]=x,nxt[tot]=head[y],head[y]=tot; 30 } 31 }G; 32 int val[N]; 33 int n; 34 #define y G.to[j] 35 int vis[N],rt,to,ban; 36 void dfs(int x){ 37 vis[x]=1; 38 for(register int j=G.head[x];j;j=G.nxt[j])if(!(j&1)){ 39 if(vis[y])return rt=x,to=y,ban=j,void(); 40 else dfs(y); 41 } 42 } 43 ll f[N][2],res,ans; 44 void dp1(int x,int fa){ 45 vis[x]=1,f[x][1]=val[x]; 46 for(register int j=G.head[x];j;j=G.nxt[j])if(y^fa&&j^ban&&j^(ban^1)){ 47 dp1(y,x); 48 f[x][0]+=_max(f[y][0],f[y][1]); 49 f[x][1]+=f[y][0]; 50 } 51 } 52 void dp2(int x,int fa){ 53 f[x][1]=val[x],f[x][0]=0; 54 for(register int j=G.head[x];j;j=G.nxt[j])if(y^fa&&j^ban&&j^(ban^1)){ 55 dp2(y,x); 56 f[x][0]+=_max(f[y][0],f[y][1]); 57 f[x][1]+=f[y][0]; 58 } 59 if(x==to)f[x][1]=0; 60 } 61 #undef y 62 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 63 read(n); 64 for(register int i=1,x;i<=n;++i)read(val[i]),read(x),G.add(i,x); 65 for(register int i=1;i<=n;++i)if(!vis[i]){ 66 dfs(i);dp1(rt,0),res=f[rt][0]; 67 dp2(rt,0),MAX(res,f[rt][1]),ans+=res; 68 } 69 printf("%lld\n",ans); 70 return 0; 71 }