[bzoj2561]最小生成树

考虑一条边被选入最小生成树的条件,即所有比他小的边不能让这条边所连接的两个点连通,那么将所有边建成两条有向边并跑这两个点的最小割即可(最大生成树同理,但不可以一起做)。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 20005
 4 #define inf 0x3f3f3f3f
 5 struct ji{
 6     int nex,to,len;
 7 }edge[N*40];
 8 struct ji2{
 9     int x,y,z;
10     bool operator < (const ji2 &k)const{
11         return z<k.z;
12     }
13 }a[N*10];
14 queue<int>q;
15 int E,n,m,x,y,head[N],work[N],d[N];
16 void add(int x,int y,int z){
17     edge[E].nex=head[x];
18     edge[E].to=y;
19     edge[E].len=z;
20     head[x]=E++;
21     if (E&1)add(y,x,0);
22 }
23 bool bfs(){
24     memset(d,-1,sizeof(d));
25     q.push(a[0].x);
26     d[a[0].x]=0;
27     while (!q.empty()){
28         int k=q.front();
29         q.pop();
30         for(int i=head[k];i!=-1;i=edge[i].nex)
31             if ((edge[i].len)&&(d[edge[i].to]<0)){
32                 d[edge[i].to]=d[k]+1;
33                 q.push(edge[i].to);
34             }
35     }
36     return d[a[0].y]>=0;
37 }
38 int dfs(int k,int s){
39     if (k==a[0].y)return s;
40     int p;
41     for(int &i=work[k];i!=-1;i=edge[i].nex)
42         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
43             p=dfs(edge[i].to,min(s,edge[i].len));
44             if (p){
45                 edge[i].len-=p;
46                 edge[i^1].len+=p;
47                 return p;
48             }
49         }
50     return 0;
51 }
52 int dinic(){
53     int k,ans=0;
54     while (bfs()){
55         memcpy(work,head,sizeof(head));
56         while (k=dfs(a[0].x,inf))ans+=k;
57     }
58     return ans;
59 }
60 int main(){
61     scanf("%d%d",&n,&m);
62     m++;
63     for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
64     a[0]=a[m];
65     sort(a+1,a+m+1);
66     int ans=0;
67     for(int i=0;i<2;i++){
68         memset(head,-1,sizeof(head));
69         E=0;
70         for(int j=1;j<=m;j++)
71             if ((!i)&&(a[j]<a[0])||(i)&&(a[0]<a[j])){
72                 add(a[j].x,a[j].y,1);
73                 add(a[j].y,a[j].x,1);
74             }
75         ans+=dinic();
76     }
77     printf("%d",ans);
78 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249676.html