首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。