标签:des style blog color java os io strong
题目大意:给你一个n,m,k。n行,m列。然后给你每一行的总和,与每一列的总和,让你在这个n*m的矩阵里面填一个小于等于k的数字,使得满足每一列,每一行的和。如果没有输出“Impossible”,有多解输出“Not Unique”,有唯一的解输出“Unique”,并输出他的解。
从源点到每一行的和建边容量为它的总和,从汇点到列建边容量为它的总和。然后行到列建边容量为数据上限K。然后求是否存在满流,如果从在在判断是否唯一。判唯一的时候,你要看中间是否存在环流,这样的话有些值 你取多少是不会收到影响的。
2 2 4 4 2 4 2 4 2 2 2 2 5 0 5 4 1 4 3 9 1 2 3 3
Not Unique Impossible Unique 1 2 3 3
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <iomanip> #include <stdio.h> #include <string> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> #define eps 1e-12 ///#define M 1000100 #define LL __int64 ///#define LL long long ///#define INF 0x7ffffff #define INF 0x3f3f3f3f #define PI 3.1415926535898 #define zero(x) ((fabs(x)<eps)?0:x) using namespace std; const int maxn = 1010; int cnt; int n, m; int cur[maxn], head[maxn]; int dis[maxn], gap[maxn]; int aug[maxn], pre[maxn]; int deep[maxn]; struct node { int v, w; int next; } f[500100]; void init() { cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w) { f[cnt].v = v; f[cnt].w = w; f[cnt].next = head[u]; head[u] = cnt++; f[cnt].v = u; f[cnt].w = 0; f[cnt].next = head[v]; head[v] = cnt++; } int SAP(int s, int e, int n) { int max_flow = 0, v, u = s; int id, mindis; aug[s] = INF; pre[s] = -1; memset(dis, 0, sizeof(dis)); memset(gap, 0, sizeof(gap)); gap[0] = n; for (int i = 0; i <= n; ++i) cur[i] = head[i];/// 初始化当前弧为第一条弧 while (dis[s] < n) { bool flag = false; if (u == e) { max_flow += aug[e]; for (v = pre[e]; v != -1; v = pre[v]) /// 路径回溯更新残留网络 { id = cur[v]; f[id].w -= aug[e]; f[id^1].w += aug[e]; aug[v] -= aug[e]; /// 修改可增广量,以后会用到 if (f[id].w == 0) u = v; /// 不回退到源点,仅回退到容量为0的弧的弧尾 } } for (id = cur[u]; id != -1; id = f[id].next)/// 从当前弧开始查找允许弧 { v = f[id].v; if (f[id].w > 0 && dis[u] == dis[v] + 1) /// 找到允许弧 { flag = true; pre[v] = u; cur[u] = id; aug[v] = min(aug[u], f[id].w); u = v; break; } } if (flag == false) { if (--gap[dis[u]] == 0) break; ///gap优化,层次树出现断层则结束算法 mindis = n; cur[u] = head[u]; for (id = head[u]; id != -1; id = f[id].next) { v = f[id].v; if (f[id].w > 0 && dis[v] < mindis) { mindis = dis[v]; cur[u] = id; /// 修改标号的同时修改当前弧 } } dis[u] = mindis + 1; gap[dis[u]]++; if (u != s) u = pre[u]; /// 回溯继续寻找允许弧 } } return max_flow; } int mp[410][410]; int vis[maxn]; bool dfs(int x, int fa) { for(int i = head[x]; i != -1; i = f[i].next) { if(i == (fa^1)) continue; if(!f[i].w) continue; if(vis[f[i].v]) return true; vis[f[i].v] = 1; if(dfs(f[i].v, i)) return true; vis[f[i].v] = 0; } return false; } int main() { int k; int x, y; int S; int T; int en; int sum1; int sum2; while(~scanf("%d %d %d",&n, &m, &k)) { init(); sum1 = sum2 = 0; S = 0; T = n+m+1; en = T+1; for(int i = 1; i <= n; i++) { scanf("%d",&x); sum1 += x; add(S, i, x); for(int j = 1; j <= m; j++) add(i, j+n, k); } for(int i = 1; i <= m; i++) { scanf("%d",&y); sum2 += y; add(i+n, T, y); } if(sum1 != sum2) { puts("Impossible"); continue; } int ans = SAP(S, T, en); if(ans != sum1) { puts("Impossible"); continue; } memset(vis, 0, sizeof(vis)); int flag = 0; for(int i = 1; i <= n; i++) { if(dfs(i, -1)) { flag = 1; break; } } if(flag) { puts("Not Unique"); continue; } memset(mp, 0, sizeof(mp)); puts("Unique"); for(int i = 1; i <= n; i++) { for(int j = head[i]; j != -1; j = f[j].next) { int x = f[j].v; if(x > n && x <= n+m) mp[i][x-n] = k-f[j].w; } } for(int i = 1; i <= n; i++) { for(int j = 1; j < m; j++) printf("%d ",mp[i][j]); printf("%d\n",mp[i][m]); } } return 0; }
HDU 4888 Redraw Beautiful Drawings(最大流),布布扣,bubuko.com
HDU 4888 Redraw Beautiful Drawings(最大流)
标签:des style blog color java os io strong
原文地址:http://blog.csdn.net/xu12110501127/article/details/38662287