HDU 3820 Golden Eggs
2017-04-12 21:04
399 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3820
题意:
n*m的格子,每个格子放金蛋或银蛋,每个格子的金蛋和银蛋都有一个对应的点权,如果有两个金蛋相连,则需要G的代价,如果有两个银蛋相连,需要S的代价。
思路:
这道题和HDU的格子取数是一个套路。
在前面的格子取数问题中,我们奇偶建图,相邻点之间连INF就代表这两个点中至少会选择一个,由于是最小割,肯定是选择权值小的点。这道题目的建图稍微复杂点,因为每个格子有三种选择,即可以选择放金蛋或是放银蛋或空着。首先,我们还是要奇偶建图,把一方的金蛋与源点相连,银蛋与汇点相连,而另一方的金蛋与汇点相连,银蛋与源点相连。每一方的金蛋与自己的银蛋相连,容量为INF,说明要么放金蛋,要么放银蛋。而相邻的蛋颜色相同时则边的容量为代价。
题意:
n*m的格子,每个格子放金蛋或银蛋,每个格子的金蛋和银蛋都有一个对应的点权,如果有两个金蛋相连,则需要G的代价,如果有两个银蛋相连,需要S的代价。
思路:
这道题和HDU的格子取数是一个套路。
在前面的格子取数问题中,我们奇偶建图,相邻点之间连INF就代表这两个点中至少会选择一个,由于是最小割,肯定是选择权值小的点。这道题目的建图稍微复杂点,因为每个格子有三种选择,即可以选择放金蛋或是放银蛋或空着。首先,我们还是要奇偶建图,把一方的金蛋与源点相连,银蛋与汇点相连,而另一方的金蛋与汇点相连,银蛋与源点相连。每一方的金蛋与自己的银蛋相连,容量为INF,说明要么放金蛋,要么放银蛋。而相邻的蛋颜色相同时则边的容量为代价。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int maxn = 1e5 + 5; const int INF=0x3f3f3f3f; struct Edge { int from,to,cap,flow; Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} }; struct Dinic { int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int cur[maxn]; int d[maxn]; void init(int n) { this->n=n; for(int i=0;i<n;++i) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back( Edge(from,to,cap,0) ); edges.push_back( Edge(to,from,0,0) ); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { queue<int> Q; memset(vis,0,sizeof(vis)); vis[s]=true; d[s]=0; Q.push(s); while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(!vis[e.to] && e.cap>e.flow) { vis[e.to]=true; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a) { if(x==t || a==0) return a; int flow=0, f; for(int &i=cur[x];i<G[x].size();++i) { Edge &e=edges[G[x][i]]; if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) { e.flow +=f; edges[G[x][i]^1].flow -=f; flow +=f; a -=f; if(a==0) break; } } return flow; } int Maxflow(int s,int t) { this->s=s; this->t=t; int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow +=DFS(s,INF); } return flow; } }DC; int n,m; int G,S; int map[105][55]; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; int main() { //freopen("D:\\input.txt","r",stdin); int kase=0; int T; scanf("%d",&T); while(T--) { int sum=0; scanf("%d%d%d%d",&n,&m,&G,&S); int src=0,dst=2*n*m+1; DC.init(dst+1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&map[i][j]); sum+=map[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&map[i+n][j]); sum+=map[i+n][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int id1=(i-1)*m+j; int id2=(i+n-1)*m+j; int t=(i+j)%2; //0为金色 if(t==0) { DC.AddEdge(src,id1,map[i][j]); //金 DC.AddEdge(id2,dst,map[i+n][j]); //银 DC.AddEdge(id1,id2,INF); for(int k=0;k<4;k++) { int x=i+dx[k]; int y=j+dy[k]; if(x<1||x>n||y<1||y>m) continue; DC.AddEdge(id1,(x+n-1)*m+y,G); } } else { DC.AddEdge(src,id1,map[i+n][j]); DC.AddEdge(id2,dst,map[i][j]); DC.AddEdge(id1,id2,INF); for(int k=0;k<4;k++) { int x=i+dx[k]; int y=j+dy[k]; if(x<1||x>n||y<1||y>m) continue; DC.AddEdge(id1,(x+n-1)*m+y,S); } } } int ans=sum-DC.Maxflow(src,dst); printf("Case %d: %d\n",++kase,ans); } return 0; }
相关文章推荐
- HDU 5815 Golden Week
- hdu 4814 Golden Radio Base
- HDU3820 Golden Eggs(最小割)
- hdu 3820
- HDU 4814 Golden Radio Base
- 2013 Asia Regional Changchun HDU - 4814 Golden Radio Base (进制模拟)
- hdu 3820 Golden Eggs(最小割+SAP)
- 2013ICPC长春 HDU 4814 Golden Radio Base 乱搞
- HDU 3820 Golden Eggs( 最小割 奇特建图)经典
- HDU 4814 Golden Radio Base
- [hdu 4814]Golden Radio Base 找规律
- HDU 3820 Golden Eggs (最小割)
- HDU 4814 Golden Radio Base(2013 ACM/ICPC 长春赛区现场赛)
- hdu 3820 Golden Eggs 最小割
- hdu 3820 Golden Eggs(最小割,最大点权独立集+拆点)
- HDU 5815 Golden Week
- HDU 4814 Golden Radio Base 模拟
- HDU 3820 Golden Eggs(最大独立集)
- HDU 4814 Golden Radio Base
- HDU 4814 Golden Radio Base