1. 程式人生 > >GYM 101128 F.Landscaping(網絡流)

GYM 101128 F.Landscaping(網絡流)

emp oid vector cstring set turn pin 網絡 pen

鏈接:http://codeforces.com/gym/101128

題意:給定一個n*m的地,每塊有兩種高度,可以花費b將某一塊高變低或低變高,有n+m輛車,分別從左往右、從上往下走,經過不同高度的地交界處花費為a,求最小花費。

分析:想到網絡流,沒想到怎麽構造。。。實際上就是要把高和低分開,同時存在高變低和低變高,求最小費用,因此相鄰連流量為a的邊,源點向低地連流量為b的邊,高地向匯點連流量為b的邊,最後求一下最小割即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5
#include<queue> 6 using namespace std; 7 const int delta=50; 8 const int maxn=2505,inf=1e9+5; 9 char field[55][55]; 10 struct Edge{ 11 int from,to,cap,flow; 12 Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} 13 }; 14 struct EdmodsKarp{ 15 int n; 16 vector<Edge> edges;
17 vector<int> G[maxn]; 18 int a[maxn]; 19 int p[maxn]; 20 void init(int n){ 21 for(int i=0;i<n;i++)G[i].clear(); 22 edges.clear(); 23 this->n=n; 24 } 25 void AddEdge(int from,int to,int cap){ 26 edges.push_back(Edge(from,to,cap,0)); 27
edges.push_back(Edge(to,from,0,0)); 28 G[from].push_back(edges.size()-2); 29 G[to].push_back(edges.size()-1); 30 } 31 int Maxflow(int s,int t){ 32 int flow=0; 33 while(1){ 34 memset(a,0,sizeof(a)); 35 queue<int> Q; 36 Q.push(s); 37 a[s]=inf; 38 while(!Q.empty()){ 39 int x=Q.front();Q.pop(); 40 for(int i=0;i<G[x].size();i++){ 41 Edge &e=edges[G[x][i]]; 42 if(!a[e.to]&&e.cap>e.flow){ 43 p[e.to]=G[x][i]; 44 a[e.to]=min(a[x],e.cap-e.flow); 45 Q.push(e.to); 46 } 47 } 48 if(a[t])break; 49 } 50 if(!a[t])break; 51 for(int u=t;u!=s;u=edges[p[u]].from){ 52 edges[p[u]].flow+=a[t]; 53 edges[p[u]^1].flow-=a[t]; 54 } 55 flow+=a[t]; 56 } 57 return flow; 58 } 59 }ek; 60 void add(int s,int t,int cap){ 61 ek.AddEdge(s,t,cap); 62 ek.AddEdge(t,s,cap); 63 } 64 int main(){ 65 // freopen("e:\\in.txt","r",stdin); 66 int n,m,a,b; 67 scanf("%d%d%d%d",&n,&m,&a,&b); 68 ek.init(m*n+2); 69 for(int i=0;i<n;i++){ 70 for(int j=0;j<m;j++){ 71 cin>>field[i][j]; 72 } 73 } 74 for(int i=0;i<n;i++){ 75 for(int j=0;j<m;j++){ 76 if(i<n-1){ 77 add(i*delta+j,(i+1)*delta+j,a); 78 } 79 if(j<m-1){ 80 add(i*delta+j,i*delta+j+1,a); 81 } 82 if(field[i][j]==#) 83 ek.AddEdge(i*delta+j,delta*delta+1,b); 84 else 85 ek.AddEdge(delta*delta,i*delta+j,b); 86 } 87 } 88 printf("%d\n",ek.Maxflow(delta*delta,delta*delta+1)); 89 return 0; 90 }

GYM 101128 F.Landscaping(網絡流)