51nod 1499 图(最小割)

  还是太菜了。。感觉是最小割然而不知道怎么建图。。以下是题解

  1 #include<iostream>
  2 #include<vector>
  3 #include<queue>
  4 #include<stack>
  5 #include<cstdio>
  6 #include<cstring>
  7 using namespace std;
  8 const int maxn=1e3+5,INF=1e9;
  9 struct Edge{
 10     int from,to,cap,flow;
 11     Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
 12 };
 13 struct ISAP{
 14     int n,s,t;
 15     vector<Edge> edges;
 16     vector<int> G[maxn];
 17     bool vis[maxn];
 18     int d[maxn];
 19     int cur[maxn];
 20     int p[maxn];
 21     int num[maxn];
 22 
 23     void init(int n){
 24         this->n=n;
 25         edges.clear();
 26         for(int i=0;i<n;i++)G[i].clear();
 27     }
 28 
 29     void AddEdge(int from,int to,int cap){
 30         edges.push_back(Edge(from,to,cap,0));
 31         edges.push_back(Edge(to,from,0,0));
 32         G[from].push_back(edges.size()-2);
 33         G[to].push_back(edges.size()-1);
 34     }
 35 
 36     void BFS(){
 37         memset(vis,0,sizeof(vis));
 38         queue<int> Q;
 39         Q.push(t);
 40         d[t]=0;
 41         vis[t]=1;
 42         while(!Q.empty()){
 43             int x=Q.front();Q.pop();
 44             for(int i=0;i<G[x].size();i++){
 45                 Edge &e=edges[G[x][i]^1];
 46                 if(e.flow==e.cap)continue;
 47                 if(!vis[e.from]){
 48                     vis[e.from]=1;
 49                     d[e.from]=d[x]+1;
 50                     Q.push(e.from);
 51                 }
 52             }
 53         }
 54     }
 55 
 56     int Augment(){
 57         int x=t,a=INF;
 58         while(x!=s){
 59             Edge &e=edges[p[x]];
 60             a=min(a,e.cap-e.flow);
 61             x=edges[p[x]].from;
 62         }
 63         x=t;
 64         while(x!=s){
 65             edges[p[x]].flow+=a;
 66             edges[p[x]^1].flow-=a;
 67             x=edges[p[x]].from;
 68         }
 69         return a;
 70     }
 71 
 72     int Maxflow(int s,int t){
 73         this->s=s;this->t=t;
 74         int flow=0;
 75         BFS();
 76         memset(num,0,sizeof(num));
 77         for(int i=0;i<n;i++)num[d[i]]++;
 78         int x=s;
 79         memset(cur,0,sizeof(cur));
 80         while(d[s]<n){
 81             if(x==t){
 82                 flow+=Augment();
 83                 x=s;
 84             }
 85             int ok=0;
 86             for(int i=cur[x];i<G[x].size();i++){
 87                 Edge &e=edges[G[x][i]];
 88                 if(e.cap>e.flow&&d[x]==d[e.to]+1){
 89                     ok=1;
 90                     p[e.to]=G[x][i];
 91                     cur[x]=i;
 92                     x=e.to;
 93                     break;
 94                 }
 95             }
 96             if(!ok){
 97                 int m=n-1;
 98                 for(int i=0;i<G[x].size();i++){
 99                     Edge &e=edges[G[x][i]];
100                     if(e.cap>e.flow)m=min(m,d[e.to]);
101                 }
102                 if(--num[d[x]]==0)break;
103                 num[d[x]=m+1]++;
104                 cur[x]=0;
105                 if(x!=s)x=edges[p[x]].from;
106             }
107         }
108         return flow;
109     }
110 }isap;
111 
112 inline int ABS(int x){return x>=0?x:-x;}
113 int n,m;
114 int g[maxn][maxn];
115 int main(){
116     memset(g,0,sizeof(g));
117     scanf("%d%d",&n,&m);
118     isap.init(n+2);
119     for(int i=0;i<m;i++){
120         int u,v;
121         scanf("%d%d",&u,&v);
122         g[u][v]=1;
123         g[v][u]=1;
124     }
125     int ans=0;
126     for(int i=1;i<=n;i++){
127         for(int j=1;j<=n;j++){
128             if(i==j)continue;
129             if(g[i][j]){
130                 isap.AddEdge(0,i,ABS(i-j));
131             }else{
132                 isap.AddEdge(i,n+1,ABS(i-j));
133             }
134             isap.AddEdge(i,j,ABS(i-j));
135             ans+=ABS(i-j);
136         }
137     }
138     ans-=isap.Maxflow(0,n+1);
139     ans/=2;
140     printf("%d
",ans);
141     return 0;
142 }
原文地址:https://www.cnblogs.com/7391-KID/p/7670289.html