模板(网络流判断:是否存在一个一直行列和的矩阵)
来源:互联网 发布:免费进销存 知乎 编辑:程序博客网 时间:2024/06/07 00:55
模版如下://HDU 4888:http://acm.hdu.edu.cn/showproblem.php?pid=4888
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;#define ll __int64#define eps 1e-8const ll Mod=(1e9+7);const int maxn = 510;const int maxm = 50100;int n,m,k;int r[maxn],c[maxn];int ma[maxn][maxn];const int maxnode = 1000 + 5;const int maxedge = 2*161000 + 5;const int oo = 1000000000;int node, src, dest, nedge;int head[maxnode], point[maxedge], next1[maxedge], flow[maxedge], capa[maxedge];//point[x]==y表示第x条边连接y,head,next为邻接表,flow[x]表示x边的动态值,capa[x]表示x边的初始值int dist[maxnode], Q[maxnode], work[maxnode];//dist[i]表示i点的等级void init(int _node, int _src, int _dest){//初始化,node表示点的个数,src表示起点,dest表示终点 node = _node; src = _src; dest = _dest; for (int i = 0; i < node; i++) head[i] = -1; nedge = 0;}void addedge(int u, int v, int c1, int c2){//增加一条u到v流量为c1,v到u流量为c2的两条边 point[nedge] = v, capa[nedge] = c1, flow[nedge] = 0, next1[nedge] = head[u], head[u] = (nedge++); point[nedge] = u, capa[nedge] = c2, flow[nedge] = 0, next1[nedge] = head[v], head[v] = (nedge++);}bool dinic_bfs(){ memset(dist, 255, sizeof (dist)); dist[src] = 0; int sizeQ = 0; Q[sizeQ++] = src; for (int cl = 0; cl < sizeQ; cl++) for (int k = Q[cl], i = head[k]; i >= 0; i = next1[i]) if (flow[i] < capa[i] && dist[point[i]] < 0){ dist[point[i]] = dist[k] + 1; Q[sizeQ++] = point[i]; } return dist[dest] >= 0;}int dinic_dfs(int x, int exp){ if (x == dest) return exp; for (int &i = work[x]; i >= 0; i = next1[i]){ int v = point[i], tmp; if (flow[i] < capa[i] && dist[v] == dist[x] + 1 && (tmp = dinic_dfs(v, min(exp, capa[i] - flow[i]))) > 0){ flow[i] += tmp; flow[i^1] -= tmp; return tmp; } } return 0;}int dinic_flow(){ int result = 0; while (dinic_bfs()){ for (int i = 0; i < node; i++) work[i] = head[i]; while (1){ int delta = dinic_dfs(src, oo); if (delta == 0) break; result += delta; } } return result;}//建图前,运行一遍init();//加边时,运行addedge(a,b,c,0),表示点a到b流量为c的边建成(注意点序号要从0开始)//求解最大流运行dinic_flow(),返回值即为答案bool judge(int sumrow){ int flow = 1; for(int i = 1;i <= n;i++) for(int j = n+1;j <= n+m;j ++) addedge(i,j,k,0); flow=dinic_flow(); if(flow != sumrow) return false; return true;}int main(){ //k为能填原图能填的数字的最大值 while(scanf("%d%d%d",&n,&m,&k) != EOF){ init(n+m+2,0,n+m+1); int flag = 0; int sumrow = 0,colrow = 0; for(int i = 1;i <= n;i++){ scanf("%d",&r[i]); addedge(0,i,r[i],0); sumrow += r[i]; if(r[i]<0 || r[i]>m*k) flag = 1; } for(int j = 1;j <= m;j ++){ scanf("%d",&c[j]); addedge(j+n,n+m+1,c[j],0); colrow += c[j]; if(c[j]<0 || c[j]>n*k) flag = 1; } if(sumrow != colrow){ printf("Impossible\n"); continue; } if(!judge(sumrow)) flag = 1; if(flag == 1){ printf("Impossible\n"); continue; } memset(ma,-1,sizeof(ma)); int i,j; for(i=1;i<=n;i++) if(r[i]==0) for(j=1;j<=m;j++) ma[i][j]=0; for(j=1;j<=m;j++) if(c[j]==0) for(i=1;i<=n;i++) ma[i][j]=0; int tt=2; int sum,num,temp; while(tt--) { for(i=1;i<=n;i++) { if(r[i]==0) { for(j=1;j<=m;j++) if(ma[i][j]==-1) ma[i][j]=0; continue; } sum=0; num=0; for(j=1;j<=m;j++) { if(ma[i][j]==-1) { num++; temp=j; sum+=min(k,c[j]); } } if(num==1) { ma[i][temp]=r[i]; r[i]-=ma[i][temp]; c[temp]-=ma[i][temp]; continue; } else if(sum==r[i]) { for(j=1;j<=m;j++) { if(ma[i][j]==-1) { ma[i][j]=min(k,c[j]); r[i]-=ma[i][j]; c[j]-=ma[i][j]; } } } } for(j=1;j<=m;j++) { if(c[j]==0) { for(i=1;i<=n;i++) if(ma[i][j]==-1) ma[i][j]=0; continue; } sum=0; num=0; for(i=1;i<=n;i++) { if(ma[i][j]==-1) { num++; temp=i; sum+=min(k,r[i]); } } if(num==1) { ma[temp][j]=c[j]; r[temp]-=ma[temp][j]; c[j]-=ma[temp][j]; continue; } else if(sum==c[j]) { for(i=1;i<=n;i++) { if(ma[i][j]==-1) { ma[i][j]=min(k,r[i]); r[i]-=ma[i][j]; c[j]-=ma[i][j]; } } } } } flag=0; for(i=1;i<=n;i++) if(r[i]!=0) { flag=1; break; } for(j=1;j<=m;j++) if(c[j]!=0) { flag=1; break; } if(flag==1) printf("Not Unique\n"); else { printf("Unique\n"); for(i=1;i<=n;i++) { for(j=1;j<m;j++) printf("%d ",ma[i][j]); printf("%d\n",ma[i][m]); } } } return 0;}
3 0
- 模板(网络流判断:是否存在一个一直行列和的矩阵)
- hdu 4975 A simple Gaussian elimination problem.(网络流,判断矩阵是否存在)
- 客户端判断一个网络文件是否存在
- 判断网络是否存在
- 判断二叉树是否平衡、求二叉树的镜像、按行列有序矩阵中快速查找元素是否存在
- 判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。(回溯法)
- 在杨氏矩阵中判断一个数是否存在
- 判断网络上的图片是否存在
- 判断SDCARD扫描状态和是否存在,网络是否可用
- android判断是否存在网络
- 判断网络图片是否存在
- 判断当前网络是否存在
- iOS判断是否存在网络
- 判断网络图片是否存在
- hdu4975 行列和构造矩阵(dp判断唯一性)
- 在一个按行列递增的二维数组中查找一个数是否存在
- 判断一个表是否存在
- 判断一个对象是否存在
- MFC 基于对话框的项目如何添加子对话框以及相关知识
- 【比特币】P2P网络
- hdu 1392 Surround the Trees(凸包)
- 【转】SQL Server 2008 R2编写脚本时智能提示功能丢失的处理
- 小黑小波比.Ubuntu修改文件夹权限.
- 模板(网络流判断:是否存在一个一直行列和的矩阵)
- 学Java学Android开发
- PHP explode() 字符串转换数组
- poj 2470 Ambiguous permutations
- 黑马程序员-----JAVA的概述
- 动态代理
- timer_pending
- 背包学习——神秘的饭卡
- Docker Security docker 容器安全