The problem at that time dozen school when there is a train of thought, but the code ability is poor, did not write out
After looking at the Zimpha giant's key, read the feeling basically almost
The core idea: is to find the cutting point, and then into the forest, and then the tree DP can be done
The key is in the re-composition, after the end of the point, a cut point at least two points in the double inside, this time
Cut the point out, respectively, and point double-side, that is, the point of the end of the double is not included in the cut point, this can be a man-made
(like some point double inside contains only a bridge edge, if the cut point out, point double inside no point, this time to set the weight of the double-value product to 1 good)
Then said is the tree-shaped DP, in fact, is the inverse of the work, this is very simple, the tree DP only deal with the answer of the cut point
Note: This diagram is not connected, this is a point, and there are outliers, I have been WA at the point of isolation, (my point double template can only solve at least two points of the connectivity graph, this problem plump my template, thanks)
#include <stdio.h>#include<iostream>#include<algorithm>#include<string.h>#include<vector>#include<math.h>#include<stack>#include<map>using namespaceStd;typedefLong LongLL;Const intN = 1e5+5;ConstLL mod = 1e9+7; ll Qpow (ll A,ll b) {LL ret=1; while(b) {if(b&1) ret= (ret*a)%MoD; b>>=1; A= (a*a)%MoD; } returnret;}inthead[n<<1],tot,t,n,m;structedge{intU,v,next;} Edge[n*4];voidAddedge (intUintv) {edge[tot].u=u; EDGE[TOT].V=v; Edge[tot].next=Head[u]; Head[u]=tot++;}intLow[n],dfn[n],clk,cnt,belbcc[n];BOOLIscut[n];vector<int>Bcc[n],cut;stack<int>s;voidinit () {memset (DFN,0,sizeof(DFN)); memset (Head,-1,sizeof(head)); memset (BELBCC,0,sizeof(BELBCC)); Tot=clk=cnt=0; Cut.clear ();} LL W[n],bccw[n<<1],ret[n],blkw[n<<1],zong;BOOLvis[n<<1];intblk,bel[n<<1];voidDfsintUintf) {Dfn[u]=low[u]=++CLK; intChild=0; if(head[u]==-1){ ++cnt;bcc[cnt].clear (); Bcc[cnt].push_back (U); Belbcc[u]=CNT; return ; } for(intI=head[u];~i;i=Edge[i].next) { intto=edge[i].v; if(!Dfn[to]) { ++Child;s.push (i);d FS (to,u); Low[u]=min (low[u],low[to]); if(low[to]>=Dfn[u]) {Iscut[u]=true; ++cnt;intx;bcc[cnt].clear (); Do{x=s.top (); S.pop (); if(belbcc[edge[x].u]!=CNT) {Bcc[cnt].push_back (EDGE[X].U); BELBCC[EDGE[X].U]=CNT; } if(belbcc[edge[x].v]!=CNT) {Bcc[cnt].push_back (EDGE[X].V); BELBCC[EDGE[X].V]=CNT; } } while(x!=i); } } Else if(dfn[to]<dfn[u]&&to!=f) {S.push (i); Low[u]=min (low[u],dfn[to]); } } if(!f&&child==1) iscut[u]=false; if(Iscut[u]) cut.push_back (n+u), bccw[n+u]=w[u];}voidPredfs (intUintf) {Bel[u]=blk;blkw[blk]=blkw[blk]*bccw[u]%MoD; Vis[u]=true; for(intI=head[u];~i;i=Edge[i].next) { intv=edge[i].v; if(v==f)Continue; Predfs (V,u); }}ll TREEDP (intUintf) {LL Pro=1, sum=0, TMP; Vis[u]=false; for(intI=head[u];~i;i=Edge[i].next) { intv=edge[i].v; if(v==f)Continue; TMP=TREEDP (v,u); Pro=pro*tmp%MoD; Sum= (sum+tmp)%MoD; } Pro=pro*bccw[u]%MoD; if(u>N) {tmp=Blkw[bel[u]]; TMP=tmp*qpow (pro,mod-2)%MoD; Sum= (sum+tmp)%MoD; TMP=zong-Blkw[bel[u]]; while(tmp<0) tmp+=MoD; Ret[u-n]= (sum+tmp)%MoD; } returnPro;}intMain () {scanf ("%d",&T); while(t--) {scanf ("%d%d",&n,&m); for(intI=1; i<=n;++i) scanf ("%i64d",&W[i]); Init (); for(intI=0; i<m;++i) { intU,V;SCANF ("%d%d",&u,&v); Addedge (u,v); Addedge (V,u); } for(intI=1; i<=n;++i)if(!dfn[i]) DFS (i,0); Tot=0; Memset (head,-1,sizeof(head)); for(intI=1; i<=cnt;++i) {Bccw[i]=1; for(intj=0; J<bcc[i].size (); + +j) { intu=Bcc[i][j]; if(Iscut[u]) Addedge (i,u+n), Addedge (u+n,i); Elsebccw[i]=bccw[i]*w[u]%MoD; }} Blk=0; for(intI=1; i<=cnt;++i)if(!vis[i]) {++blk;blkw[blk]=1;p Redfs (i,0);} for(intI=0; I<cut.size (); + +i)if(!vis[cut[i]]) {++blk;blkw[blk]=1;p Redfs (Cut[i],0);} Zong=0; for(intI=1; i<=blk;++i) zong= (Zong+blkw[i])%MoD; for(intI=1; i<=cnt;++i)if(Vis[i]) TREEDP (i,0); for(intI=0; I<cut.size (); + +i)if(Vis[cut[i]]) TREEDP (Cut[i],0); LL ans=0; for(intI=1; i<=n;++i) { if(Iscut[i]) {ans= (ans+1ll*i*ret[i]%mod)%MoD; Iscut[i]=false; } Else{ intk=Belbcc[i]; K=Bel[k]; LL AD=0; if(W[i]!=blkw[k]) Ad=blkw[k]*qpow (w[i],mod-2)%MoD; LL tmp=zong-Blkw[k]; while(tmp<0) tmp+=MoD; TMP= (Tmp+ad)%MoD; Ans= (ans+1ll*i*tmp%mod)%MoD; }} printf ("%i64d\n", ans); } return 0;}
View Code
HDU5739 Fantasia tree dp + dot pinch point