首页 > 代码库 > HDU 3820 Golden Eggs

HDU 3820 Golden Eggs

http://acm.hdu.edu.cn/showproblem.php?pid=3820

题意:
n*m的格子,每个格子放金蛋或银蛋,每个格子的金蛋和银蛋都有一个对应的点权,如果有两个金蛋相连,则需要G的代价,如果有两个银蛋相连,需要S的代价。

 

思路:

这道题和HDU的格子取数是一个套路。

在前面的格子取数问题中,我们奇偶建图,相邻点之间连INF就代表这两个点中至少会选择一个,由于是最小割,肯定是选择权值小的点。这道题目的建图稍微复杂点,因为每个格子有三种选择,即可以选择放金蛋或是放银蛋或空着。首先,我们还是要奇偶建图,把一方的金蛋与源点相连,银蛋与汇点相连,而另一方的金蛋与汇点相连,银蛋与源点相连。每一方的金蛋与自己的银蛋相连,容量为INF,说明要么放金蛋,要么放银蛋。而相邻的蛋颜色相同时则边的容量为代价。

  1 #include<cstdio>  2 #include<iostream>  3 #include<cstring>  4 #include<algorithm>  5 #include<vector>  6 #include<queue>  7 using namespace std;  8   9 const int maxn = 1e5 + 5; 10 const int INF=0x3f3f3f3f; 11  12 struct Edge 13 { 14     int from,to,cap,flow; 15     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} 16 }; 17  18 struct Dinic 19 { 20     int n,m,s,t; 21     vector<Edge> edges; 22     vector<int> G[maxn]; 23     bool vis[maxn]; 24     int cur[maxn]; 25     int d[maxn]; 26  27     void init(int n) 28     { 29         this->n=n; 30         for(int i=0;i<n;++i) G[i].clear(); 31         edges.clear(); 32     } 33  34     void AddEdge(int from,int to,int cap) 35     { 36         edges.push_back( Edge(from,to,cap,0) ); 37         edges.push_back( Edge(to,from,0,0) ); 38         m=edges.size(); 39         G[from].push_back(m-2); 40         G[to].push_back(m-1); 41     } 42  43     bool BFS() 44     { 45         queue<int> Q; 46         memset(vis,0,sizeof(vis)); 47         vis[s]=true; 48         d[s]=0; 49         Q.push(s); 50         while(!Q.empty()) 51         { 52             int x=Q.front(); Q.pop(); 53             for(int i=0;i<G[x].size();++i) 54             { 55                 Edge& e=edges[G[x][i]]; 56                 if(!vis[e.to] && e.cap>e.flow) 57                 { 58                     vis[e.to]=true; 59                     d[e.to]=d[x]+1; 60                     Q.push(e.to); 61                 } 62             } 63         } 64         return vis[t]; 65     } 66  67     int DFS(int x,int a) 68     { 69         if(x==t || a==0) return a; 70         int flow=0, f; 71         for(int &i=cur[x];i<G[x].size();++i) 72         { 73             Edge &e=edges[G[x][i]]; 74             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 75             { 76                 e.flow +=f; 77                 edges[G[x][i]^1].flow -=f; 78                 flow +=f; 79                 a -=f; 80                 if(a==0) break; 81             } 82         } 83         return flow; 84     } 85  86     int Maxflow(int s,int t) 87     { 88         this->s=s; this->t=t; 89         int flow=0; 90         while(BFS()) 91         { 92             memset(cur,0,sizeof(cur)); 93             flow +=DFS(s,INF); 94         } 95         return flow; 96     } 97 }DC; 98  99 int n,m;100 int G,S;101 int map[105][55];102 int dx[]={0,0,1,-1};103 int dy[]={1,-1,0,0};104 105 int main()106 {107     //freopen("D:\\input.txt","r",stdin);108     int kase=0;109     int T;110     scanf("%d",&T);111     while(T--)112     {113         int sum=0;114         scanf("%d%d%d%d",&n,&m,&G,&S);115         int src=http://www.mamicode.com/0,dst=2*n*m+1;116         DC.init(dst+1);117         for(int i=1;i<=n;i++)118         for(int j=1;j<=m;j++)119         {120             scanf("%d",&map[i][j]);121             sum+=map[i][j];122         }123         for(int i=1;i<=n;i++)124         for(int j=1;j<=m;j++)125         {126             scanf("%d",&map[i+n][j]);127             sum+=map[i+n][j];128         }129         for(int i=1;i<=n;i++)130         for(int j=1;j<=m;j++)131         {132             int id1=(i-1)*m+j;133             int id2=(i+n-1)*m+j;134             int t=(i+j)%2;135             //0为金色136             if(t==0)137             {138                 DC.AddEdge(src,id1,map[i][j]);    //139                 DC.AddEdge(id2,dst,map[i+n][j]);  //140                 DC.AddEdge(id1,id2,INF);141                 for(int k=0;k<4;k++)142                 {143                     int x=i+dx[k];144                     int y=j+dy[k];145                     if(x<1||x>n||y<1||y>m)  continue;146                     DC.AddEdge(id1,(x+n-1)*m+y,G);147                 }148             }149             else150             {151                 DC.AddEdge(src,id1,map[i+n][j]);152                 DC.AddEdge(id2,dst,map[i][j]);153                 DC.AddEdge(id1,id2,INF);154                 for(int k=0;k<4;k++)155                 {156                     int x=i+dx[k];157                     int y=j+dy[k];158                     if(x<1||x>n||y<1||y>m)  continue;159                     DC.AddEdge(id1,(x+n-1)*m+y,S);160                 }161             }162         }163 164         int ans=sum-DC.Maxflow(src,dst);165         printf("Case %d: %d\n",++kase,ans);166     }167     return 0;168 }

 

HDU 3820 Golden Eggs