BZOJ 2521 最小生成树(最小割)

http://www.lydsy.com/JudgeOnline/problem.php?id=2521

题意:每次能增加一条边的权值1,求最小代价让一条边保证在最小生成树里

思路:如果两个点中有环,那么这条边必须不能是环的最大边,这样子把之前所有的边权值变成V+1-v[i],无向图网络流就可以了

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 0x7fffffff
 7 struct edge{
 8     int u,v,w;
 9 }e[200005];
10 int n,m,id,dis[200005],cnt[200005],tot,S,T,nodes;
11 int flow[200005],op[200005],next[200005],first[200005],go[200005];
12 int read(){
13     char ch=getchar();int t=0,f=1;
14     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
16     return t*f;
17 }
18 void insert(int x,int y,int z){
19     tot++;
20     go[tot]=y;
21     next[tot]=first[x];
22     first[x]=tot;
23     flow[tot]=z;
24 }
25 void add(int x,int y,int z){
26     insert(x,y,z);op[tot]=tot+1;
27     insert(y,x,0);op[tot]=tot-1;
28 }
29 void add2(int x,int y,int z){
30     insert(x,y,z);op[tot]=tot+1;
31     insert(y,x,z);op[tot]=tot-1;
32 }
33 int dfs(int x,int f){
34     if (x==T) return f;
35     int mn=nodes,sum=0;
36     for (int i=first[x];i;i=next[i]){
37         int pur=go[i];
38         if (flow[i]&&dis[pur]+1==dis[x]){
39             int save=dfs(pur,std::min(f-sum,flow[i]));
40             sum+=save;
41             flow[i]-=save;
42             flow[op[i]]+=save;
43             if (sum==f||dis[S]>=nodes) return sum;
44         }
45         if (flow[i]) mn=std::min(mn,dis[pur]);
46     }
47     if (sum==0){
48         cnt[dis[x]]--;
49         if (cnt[dis[x]]==0){
50             dis[S]=nodes;
51         }else{
52             dis[x]=mn+1;
53             cnt[dis[x]]++;
54         }
55     }
56     return sum;
57 }
58 int main(){
59     n=read();m=read();id=read();
60     S=0,T=n+1;nodes=n+2;
61     for (int i=1;i<=m;i++){
62         e[i].u=read();e[i].v=read();e[i].w=read();
63     }
64     add(S,e[id].u,inf);
65     add(e[id].v,T,inf);
66     for (int i=1;i<=m;i++)if (i!=id&&e[i].w<=e[id].w){
67         add2(e[i].u,e[i].v,e[id].w+1-e[i].w);
68     }
69     int ans=0;
70     while (dis[S]<nodes) ans+=dfs(S,inf);
71     printf("%d\n",ans); 
72 }

 

posted @ 2016-06-13 17:22  GFY  阅读(303)  评论(0编辑  收藏  举报