BZOJ 1497: [NOI2006]最大获利(最大权闭合图)
http://www.lydsy.com/JudgeOnline/problem.php?id=1497
题意:
思路:
论文题,只要看过论文的话就是小菜一碟啦~
每个用户群i作为一个结点分别向相应的中转站ai和中转站bi连有向边。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 typedef pair<int,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const int maxn = 55000 + 5; 16 17 int n, m; 18 int val[maxn]; 19 20 struct Edge 21 { 22 int from,to,cap,flow; 23 Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} 24 }; 25 26 struct Dinic 27 { 28 int n,m,s,t; 29 vector<Edge> edges; 30 vector<int> G[maxn]; 31 bool vis[maxn]; 32 int cur[maxn]; 33 int d[maxn]; 34 35 void init(int n) 36 { 37 this->n=n; 38 for(int i=0;i<n;++i) G[i].clear(); 39 edges.clear(); 40 } 41 42 void AddEdge(int from,int to,int cap) 43 { 44 edges.push_back( Edge(from,to,cap,0) ); 45 edges.push_back( Edge(to,from,0,0) ); 46 m=edges.size(); 47 G[from].push_back(m-2); 48 G[to].push_back(m-1); 49 } 50 51 bool BFS() 52 { 53 queue<int> Q; 54 memset(vis,0,sizeof(vis)); 55 vis[s]=true; 56 d[s]=0; 57 Q.push(s); 58 while(!Q.empty()) 59 { 60 int x=Q.front(); Q.pop(); 61 for(int i=0;i<G[x].size();++i) 62 { 63 Edge& e=edges[G[x][i]]; 64 if(!vis[e.to] && e.cap>e.flow) 65 { 66 vis[e.to]=true; 67 d[e.to]=d[x]+1; 68 Q.push(e.to); 69 } 70 } 71 } 72 return vis[t]; 73 } 74 75 int DFS(int x,int a) 76 { 77 if(x==t || a==0) return a; 78 int flow=0, f; 79 for(int &i=cur[x];i<G[x].size();++i) 80 { 81 Edge &e=edges[G[x][i]]; 82 if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 83 { 84 e.flow +=f; 85 edges[G[x][i]^1].flow -=f; 86 flow +=f; 87 a -=f; 88 if(a==0) break; 89 } 90 } 91 return flow; 92 } 93 94 int Maxflow(int s,int t) 95 { 96 this->s=s; this->t=t; 97 int flow=0; 98 while(BFS()) 99 { 100 memset(cur,0,sizeof(cur)); 101 flow +=DFS(s,INF); 102 } 103 return flow; 104 } 105 }DC; 106 107 int main() 108 { 109 //freopen("in.txt","r",stdin); 110 while(~scanf("%d%d",&n,&m)) 111 { 112 int src = 0, dst = n+m+1; 113 DC.init(dst+1); 114 for(int i=1;i<=n;i++) 115 { 116 scanf("%d",&val[i]); 117 DC.AddEdge(i,dst,val[i]); 118 } 119 int sum = 0; 120 for(int i=1;i<=m;i++) 121 { 122 int a,b,c; 123 scanf("%d%d%d",&a,&b,&c); 124 DC.AddEdge(src,i+n,c); 125 DC.AddEdge(i+n,a,INF); 126 DC.AddEdge(i+n,b,INF); 127 sum+=c; 128 } 129 int ans = sum-DC.Maxflow(src,dst); 130 printf("%d\n",ans); 131 } 132 return 0; 133 }