[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster费用流
来源:互联网 发布:遇见app 知乎 编辑:程序博客网 时间:2024/06/18 08:51
via. quailty
黑白染色定向
然后相当于每个点找一个后继(就能串成很多个环
每个点拆成左右两个
如果 i 是非必要点,那么左边 i 到右边 i 连一条权值 0 的边,表示我这个点连个自环(相当于就废掉了
其他的边该怎么连就怎么连
跑个最大权匹配,写成费用流就好了
#include <bits/stdc++.h>#define INF (1<<29)#define N 10000#define M 200050using namespace std;int head[N],cnt=1,tot,S,T,p[N];int dis[N],L[35][35],R[35][35],c[35][35],r[35][35],mp[35][35],inq[N];int n,m,k;int ans,fl;inline int rd() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}struct Edge{ int a,b,v,cost,next; }e[M],id;inline void add(int a,int b,int v,int cost) {// printf("%d %d %d %d\n",a,b,v,cost); e[++cnt] = (Edge){ a,b,v,cost,head[a] }, head[a] = cnt; e[++cnt] = (Edge){ b,a,0,-cost,head[b] },head[b] = cnt;}#define cp e[i].v #define B e[i].b bool SPFA() { bool flag = false; for (int i=1;i<=tot;i++) p[i] = 0, dis[i] = -(1<<29); dis[S] = 0; inq[S] = 1; queue<int> q; q.push(S); while (!q.empty()) { int u = q.front(); q.pop(); inq[u] = 0; if (u == T) flag = true; for (int i=head[u];i;i=e[i].next) if (cp > 0 && dis[u] + e[i].cost > dis[B]) { dis[B] = dis[u] + e[i].cost; p[B] = i; if (!inq[B]) inq[B]=1, q.push(B); } } return flag; } void mcf() { int g = p[T] , flow = INF; while (g) { flow = min(flow , e[g].v); g = p[ e[g].a ]; } g = p[T]; while (g) { e[g ].v -= flow; e[g^1].v += flow; ans += 1LL * e[g].cost * flow; g = p[ e[g].a ]; } fl += flow;}void solve() { memset(mp,0,sizeof(mp)); for (int i=1;i<=tot;i++) head[i] = 0; for (int i=1;i<=cnt;i++) e[i] = id; tot = 0, cnt = 1; ans = fl = 0; n = rd(), m = rd(); for (int i=1;i<=n;i++) for (int j=1;j<m;j++) c[i][j] = rd(); for (int i=1;i<n;i++) for (int j=1;j<=m;j++) r[i][j] = rd(); S = ++tot, T = ++tot; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) L[i][j] = ++tot, R[i][j] = ++tot; k = rd(); while (k--) { int x = rd(), y = rd(); mp[x][y] = 1; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) add(S, L[i][j], 1, 0), add(R[i][j], T, 1 ,0); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (!mp[i][j]) add(L[i][j], R[i][j], 1, 0); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { if ((i+j)&1) { if (i+1<=n) add(L[i][j], R[i+1][j], 1, r[i][j]); if (i-1>=1) add(L[i][j], R[i-1][j], 1, r[i-1][j]); } else { if (j+1<=m) add(L[i][j], R[i][j+1], 1, c[i][j]); if (j-1>=1) add(L[i][j], R[i][j-1], 1, c[i][j-1]); } } while (SPFA()) mcf(); if (fl != n*m) puts("Impossible"); else printf("%d\n",ans);}int main() {// freopen("bounce.in","r",stdin);// freopen("bounce.out","w",stdout); int T = rd(); for (int i=1;i<=T;i++) { printf("Case #%d: ",i); solve(); } 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 后缀自动机
- [费用流] ACM-ICPC Asia China-Final Contest J. Mr.Panda and TubeMaster
- 【Gym】101194J 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树上后缀自动机)
- thinkPHP
- 创建MySQL用户名
- JDK 工具一览
- suwstojT1(0860)
- 知识导向
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster费用流
- 数值积分(函数指针的运用)
- Spring 事务失效
- Linux 文件系统管理
- 安卓工具类集合 —— 2 TabUtil
- Linux搭建git服务器(CentOS 7)
- bzoj 1150 [CTSC2007]数据备份Backup 贪心+优先队列
- 03_mysql认证方法
- 石子合并 任意两堆合并