<题目链接>
题目大意:
给定一个连通图,每个点有点权,现在需要删除一条边,使得整张图分成两个连通块,问你删除这条边后,两联通块点权值和差值最小是多少。
解题分析:
删除一条边,使原连通图分成两个连通分量,所以删除的那条边必然是桥。为了得到所有的桥,我们对原图进行边双连通图缩点。然后对缩点后的新图,跑一遍树形DP,得到所有桥两端点权和的最小差值。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define clr(a,b) memset(a,b,sizeof(a)) 5 const int N = 1e4+5, M = 2e4+5; 6 struct Edge{ 7 int from,to,nxt; 8 }edge[M<<1],edge1[M<<1]; 9 10 int n,m,cnt,cnt1,sum,ans,dcc,tot,top; 11 int head[N],head1[N],instk[N],bel[N],dfn[N],low[N],val[N],val1[N],cost[N],stk[N]; 12 13 void init(){ 14 cnt=tot=sum=dcc=cnt1=0;ans=1e9; 15 clr(dfn,0);clr(low,0);clr(val,0);clr(head,-1);clr(head1,-1); 16 clr(instk,0);clr(cost,0); 17 } 18 void addedge(int u,int v){ edge[cnt].from=u;edge[cnt].to=v;edge[cnt].nxt=head[u];head[u]=cnt++; } 19 void addedge1(int u,int v){ edge1[cnt1].from=u;edge1[cnt1].to=v;edge1[cnt1].nxt=head1[u];head1[u]=cnt1++; } 20 21 void Tarjan(int u,int fa){ //Tarjan找边双连通分量并进行缩点 22 dfn[u]=low[u]=++tot; 23 instk[u]=1;stk[++top]=u; 24 int flag=0; 25 for(int i=head[u];~i;i=edge[i].nxt){ 26 int v=edge[i].to; 27 if(v==fa && !flag){ flag=1;continue; } //跳过搜索树上的边,这种写法能够处理重边的情况 28 if(!dfn[v]){ 29 Tarjan(v,u); 30 low[u]=min(low[u],low[v]); 31 }else if(instk[v])low[u]=min(low[u],dfn[v]); 32 } 33 if(dfn[u]==low[u]){ 34 ++dcc; 35 while(true){ 36 int v=stk[top--]; 37 bel[v]=dcc; 38 val[dcc]+=val1[v]; 39 if(v==u)break; 40 } 41 } 42 } 43 void dfs(int u,int pre){ //树形DP得到桥两边差值的最小值 44 cost[u]=val[u]; 45 for(int i=head1[u];~i;i=edge1[i].nxt){ 46 int v=edge1[i].to; 47 if(v==pre)continue; 48 dfs(v,u); 49 cost[u]+=cost[v]; 50 } 51 ans=min(ans,abs(sum-2*cost[u])); 52 } 53 int main(){ 54 while(scanf("%d%d",&n,&m)!=EOF){ 55 init(); 56 for(int i=0;i<n;i++) 57 scanf("%d",&val1[i]),sum+=val1[i]; 58 for(int i=1;i<=m;i++){ 59 int u,v;scanf("%d%d",&u,&v); 60 addedge(u,v),addedge(v,u); 61 } 62 Tarjan(0,0); 63 if( dcc==1 ) { puts("impossible");continue; } //如果该图是边双连通图,说明没有桥 64 for(int i=0;i<cnt;i++){ 65 int u,v;u=edge[i].from;v=edge[i].to; 66 if(bel[u]!=bel[v])addedge1(bel[u],bel[v]); //建立单向边 67 } 68 dfs(1,-1); 69 printf("%d\n",ans); 70 } 71 }
2019-03-02