hdu 4888 Redraw Beautiful Drawings(最大流,判环)
pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888
加入一个源点与汇点,建图例如以下:
1. 源点 -> 每一行相应的点,流量限制为该行的和
2. 每一行相应的点 -> 每一列相应的点,流量限制为 K
3. 每一列相应的点 -> 汇点,流量限制为该列的和
求一遍最大流,若最大流与矩阵之和相等,说明有解,否则无解。推断唯一解,是推断残量网络中是否存在一个长度大于2的环。若存在说明有多解,否则有唯一解,解就是每条边行i->列j的流量。
- #include <stdio.h>
- #include <iostream>
- #include <map>
- #include <set>
- #include <stack>
- #include <vector>
- #include <math.h>
- #include <string.h>
- #include <queue>
- #include <string>
- #include <stdlib.h>
- #include <algorithm>
- #define LL long long
- #define _LL __int64
- #define eps 1e-12
- #define PI acos(-1.0)
- #define C 240
- #define S 20
- using namespace std;
- const int INF = 0x3f3f3f3f;
- const int maxn = 810;
- const int maxm = 160000+810;
- struct node
- {
- int u,v,w,next;
- } edge[maxm << 1];
- int cnt,head[maxn];
- int n,m,k,s,t;
- int nn[410],mm[410];
- int maxflow;
- int vis[maxn];
- int dis[maxn];
- void init()
- {
- cnt = 0;
- memset(head,-1,sizeof(head));
- }
- void add(int u, int v, int f)
- {
- edge[cnt] = (struct node){u,v,f,head[u]};
- head[u] = cnt++;
- edge[cnt] = (struct node){v,u,0,head[v]};
- head[v] = cnt++;
- }
- bool bfs()
- {
- queue<int>que;
- while(!que.empty()) que.pop();
- memset(dis,-1,sizeof(dis));
- dis[s] = 0;
- que.push(s);
- while(!que.empty())
- {
- int u = que.front();
- que.pop();
- for(int i = head[u]; i != -1; i = edge[i].next)
- {
- int v = edge[i].v;
- if(dis[v] == -1 && edge[i].w)
- {
- dis[v] = dis[u]+1;
- que.push(v);
- }
- }
- }
- if(dis[t] == -1)
- return false;
- return true;
- }
- int dfs(int u, int delta)
- {
- if(u == t || delta == 0) return delta;
- int dd;
- int ret = 0;
- for(int i = head[u]; i != -1 && delta; i = edge[i].next)
- {
- if(dis[edge[i].v] == dis[u]+1 && (dd = dfs(edge[i].v,min(delta,edge[i].w))))
- {
- edge[i].w -= dd;
- edge[i^1].w += dd;
- delta -= dd;
- ret += dd;
- if(delta == 0)
- return ret;
- }
- }
- dis[u] = -1;
- return ret;
- }
- int Dinic()
- {
- int ret = 0;
- while(bfs())
- {
- ret += dfs(s,INF);
- }
- return ret;
- }
- int dfs_1(int u,int fa)
- {
- for(int i=head[u]; i!=-1; i=edge[i].next)
- {
- if(i==(fa^1)) continue;
- if(edge[i].w)
- {
- if(vis[edge[i].v]) return 1;
- vis[edge[i].v]=1;
- if(dfs_1(edge[i].v,i)) return 1;
- vis[edge[i].v]=0;
- }
- }
- return 0;
- }
- void putmat()
- {
- int f[410][410];
- printf("Unique\n");
- for(int u = 1; u <= n; u++)
- {
- for(int i = head[u]; i != -1; i = edge[i].next)
- {
- int v = edge[i].v;
- if(v > n && v <= n+m)
- f[u][v-n] = k - edge[i].w;
- }
- }
- for(int i = 1; i <= n; i++)
- {
- for(int j = 1; j < m; j++)
- printf("%d ",f[i][j]);
- printf("%d\n",f[i][m]);
- }
- }
- int main()
- {
- while(~scanf("%d %d %d",&n,&m,&k))
- {
- init();
- s = 0;
- t = n+m+1;
- int sum1 = 0;
- int sum2 = 0;
- for(int i = 1; i <= n; i++)
- {
- scanf("%d",&nn[i]);
- add(s,i,nn[i]);
- sum1 += nn[i];
- for(int j = 1; j <= m; j++)
- add(i,j+n,k);
- }
- for(int i = 1; i <= m; i++)
- {
- scanf("%d",&mm[i]);
- add(i+n,t,mm[i]);
- sum2 += mm[i];
- }
- if(sum1 != sum2)
- {
- printf("Impossible\n");
- }
- else
- {
- maxflow = Dinic();
- if(maxflow != sum1)
- {
- printf("Impossible\n");
- }
- else
- {
- int flag = 0;
- memset(vis,0,sizeof(vis));
- for(int i = 1; i <= n; i++)
- {
- if(dfs_1(i,-1))
- {
- flag = 1;
- break;
- }
- }
- if(flag == 1)
- printf("Not Unique\n");
- else
- putmat();
- }
- }
- }
- return 0;
- }
hdu 4888 Redraw Beautiful Drawings(最大流,判环)的更多相关文章
- hdu4888 Redraw Beautiful Drawings 最大流+判环
hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/6553 ...
- hdu 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
- hdu 4888 Redraw Beautiful Drawings 网络流
题目链接 一个n*m的方格, 里面有<=k的数, 给出每一行所有数的和, 每一列所有数的和, 问你能否还原这个图, 如果能, 是否唯一, 如果唯一, 输出还原后的图. 首先对行列建边, 源点向行 ...
- HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...
- HDU 4888 Redraw Beautiful Drawings
网络流. $s$向每一个$r[i]$连边,容量为$r[i]$. 每一个$r[i]$向每一个$c[j]$连边,容量为$k$. 每一个$c[j]$向$t$连边容量为$c[j]$. 跑最大流,中间每一条边上 ...
- HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
题意:给定n*m个格子,每个格子能填0-k 的整数.然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案. 思路:网络流,一共 n+m+2个点 源点 到行连流量为 所给的 ...
- HDU 4888 Redraw Beautiful Drawings 网络流 建图
题意: 给定n, m, k 以下n个整数 a[n] 以下m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵.若有多解输出Not Unique,若无解输出Impossib ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- HDU Redraw Beautiful Drawings 推断最大流是否唯一解
点击打开链接 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 ...
随机推荐
- Codeforces_761_E_(dfs)
E. Dasha and Puzzle time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- java项目其他基础配置
创建完maven项目之后. 1.pom.xml文件配置项目相关的架包. 2.src.main.resources下边 创建文件夹:spring以及mapper. 3.src.main.resource ...
- ProgressDialog的样式
ProgressDialog的样式有两种,一种是圆形不明确状态,一种是水平进度条状态 第一种方式:圆形进度条 final ProgressDialog dialog = new ProgressDia ...
- ZOJ - 3992 - One-Dimensional Maze (思维)
题意: 一条长度为n的直线,你一开始在位置m上 其中每个整点都有一个字符'L'或'R',如果是'L'那么你必须往左走一步,否则往右走一步 如果你到达位置1或位置n你任务就完成了 不过有可能你永远到不了 ...
- Makefile,Shell command,Shell Language 之间的联系
1. Makefile 首先要知道Makefile 是什么东西,Makefile 是一个指令文件,里面存储着自定义的命令(可以借助已有的命令创造而来)在不同的系统下对Makefile 的区别不一样,L ...
- UVA - 1619 Feel Good(扫描法)
题目: 思路: 预处理出a[i]在哪个范围区间内是最小的,然后直接遍历a数组求答案就可以了. 这个预处理的技巧巧妙的用了之前的处理结果.(大佬tql) 代码: #include <bits/st ...
- java用递归输出目录结构
package com.janson.day20180827; import java.io.File; public class TestTreeStructureDirectory { publi ...
- python socket实现文件传输(防粘包)
1.文件传输的要点: 采用iterator(迭代器对象)迭代读取,提高读取以及存取效率: 通过for line in file_handles逐行conn.send(): 2.socket粘包问题: ...
- 网络基础——TCP
TCP和UDP协议特点 1.TCP 1>.传输控制协议 2>.可靠的.面向连接的协议 3>.传输效率低 2.UDP 1>.用户数据报协议 2>.不可靠的.无连接的服务 3 ...
- Entity SQL rules for Wrapped and Unwrapped Results
Here are some rules to remember for Entity SQL queries: 1.Use SELECT VALUE when projecting more than ...