[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster
来源:互联网 发布:水经注软件 谷歌 编辑:程序博客网 时间:2024/06/08 14:56
这个题从范围来看,不难想到跟费用流有关系。但感觉跟费用流联系起来还是很难呀。拆点,这个题可以看成是给每个点找一个后继点,这一点是解题的关键。然后就是要黑白染色定向,定向这个点能走横边还是竖边,定向之后,神奇的发现所有的边都被连了有且仅有一次,这种套路估计大佬已经习以为常了吧。然后对于那些非限制格子,自己的入点连出点,保证可以不连接。然后直接看代码吧。
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 2000+5;const int inf = 1e9;int n,m;int s,e;int cnt,head[MAXN];struct node{ int u,v,w,f,next;} edge[50000];void init(){ cnt = 0; for(int i = 0; i <= e; ++i)head[i] = -1;}void add(int u,int v,int w,int f){ edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w; edge[cnt].f = f; edge[cnt].next = head[u]; head[u] = cnt++; edge[cnt].u = v; edge[cnt].v = u; edge[cnt].w = -w; edge[cnt].f = 0; edge[cnt].next = head[v]; head[v] = cnt++;}bool vis[MAXN];int dis[MAXN],pre[MAXN];bool spfa(){ for(int i = 0; i <= e; ++i) { dis[i] = -inf; pre[i] = -1; } queue<int>q; q.push(s); dis[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; int w = edge[i].w; int f = edge[i].f; if(f > 0 && dis[v] < dis[u] + w) { dis[v] = dis[u] + w; pre[v] = i; if(!vis[v]) { vis[v] = 1; q.push(v); } } } } if(pre[e] == -1)return 0; return 1;}void get_mincost(){ int max_flow = 0,min_cost = 0; while(spfa()) { int p = pre[e]; int flow = inf; while(p != -1) { flow = min(flow,edge[p].f); p = pre[edge[p].u]; } max_flow += flow; min_cost += flow*dis[e]; p = pre[e]; while(p != -1) { edge[p].f -= flow; edge[p^1].f += flow; p = pre[edge[p].u]; } } if(max_flow != n*m)puts("Impossible"); else printf("%d\n",min_cost);}int scorec[40][40],scorer[40][40];int L[40][40],R[40][40];bool tu[40][40];int main(){ int t,ca = 0; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int id = 0; for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j)L[i][j] = ++id,R[i][j] = ++id; s = 0,e = ++id; for(int i = 0; i < n; ++i) for(int j = 0; j < m-1; ++j)scanf("%d",&scorec[i][j]); for(int i = 0; i < n-1; ++i) for(int j = 0; j < m; ++j)scanf("%d",&scorer[i][j]); int E; int x,y; scanf("%d",&E); while(E--) { scanf("%d%d",&x,&y); x--,y--; tu[x][y] = 1; } init(); for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) { if((i+j)%2) { if(j+1 < m)add(L[i][j],R[i][j+1],scorec[i][j],1); if(j-1 >= 0)add(L[i][j],R[i][j-1],scorec[i][j-1],1); } else { if(i+1 < n)add(L[i][j],R[i+1][j],scorer[i][j],1); if(i-1 >= 0)add(L[i][j],R[i-1][j],scorer[i-1][j],1); } } for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) { add(s,L[i][j],0,1); add(R[i][j],e,0,1); if(!tu[i][j])add(L[i][j],R[i][j],0,1); else tu[i][j] = 0; } printf("Case #%d: ",++ca); get_mincost(); } return 0;}
阅读全文
0 0
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster费用流
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Strips 暴力+剪枝
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts 后缀自动机
- 【Gym】101194J Mr.Panda and TubeMaster
- [费用流] ACM-ICPC Asia China-Final Contest J. Mr.Panda and TubeMaster
- HDU6007-Mr. Panda and Crystal
- Gym101194C-Mr. Panda and Strips
- Mr. Panda and Crystal HDU
- Gym101194F-Mr. Panda and Fantastic Beasts
- Problem I. Mr. Panda and Crystal
- HDU 6007 Mr. Panda and Crystal (最短路 + 完全背包)
- 2016 China Final F Mr. Panda and Fantastic Beasts
- Gym 101194F Mr. Panda and Fantastic Beasts
- hdu 6007 Mr. Panda and Crystal(最短路+完全背包)
- Codeforces 101206 I & HDU 6007 Mr. Panda and Crystal
- Hdu 6007 Mr. Panda and Crystal 最短路+完全背包
- BJ模拟 Mr. Panda and Fantastic Beats(广义后缀自动机、trie树上后缀自动机)
- LAMP架构介绍
- 在线测试--图
- 14.大小写字母互换
- ScrollView 相关判断
- 【Point Cloud Library(PCL)入门】之简介与安装
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster
- Unicode与ASCII
- 区间第k小 poj2104 可持久化线段树
- 漂亮的Adapter模式-体会RecyclerView的设计实现
- 手把手教你webpack3(8)url-Loader配置简述
- Spring注解方法学习笔记
- Java设计模式之责任链模式
- 第一章作业2-算法时间复杂度和空间复杂度
- 吴恩达机器学习课程(一)之梯度下降原理