51nod 1499 图(最小割)
Posted 7391_KID
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n",ans); 141 return 0; 142 }
以上是关于51nod 1499 图(最小割)的主要内容,如果未能解决你的问题,请参考以下文章