hdu 4975 A simple Gaussian elimination problem.(网络流,推断矩阵是否存在)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975
the table after that.
However Dragon's mom came back and found what he had done. She would give dragon a feast if Dragon could reconstruct the table, otherwise keep Dragon hungry. Dragon is so young and so simple so that the original numbers in the table are one-digit number (e.g.
0-9).
Could you help Dragon to do that?
There are three lines for each block. The first line contains two integers N(<=500) and M(<=500), showing the number of rows and columns.
The second line contains N integer show the sum of each row.
The third line contains M integer show the sum of each column.
output one line contains only: "So young!", otherwise (only one way to reconstruct the table) you should output: "So simple!".
3
1 1
5
5
2 2
0 10
0 10
2 2
2 2
2 2
Case #1: So simple!
Case #2: So naive!
Case #3: So young!
题意:
给出每行每列的和,问是否存在这种表格;每一个小格放的数字仅仅能是0--9。
官方题解:http://blog.sina.com.cn/s/blog_6bddecdc0102v01l.html
代码例如以下:(套用别人HDU4888的模板)
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
#define ll __int64
#define eps 1e-8
const 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 = 10000 + 5;
const int maxedge = 2*1000000 + 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,cost = 0;
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为能填原图能填的数字的最大值
int t;
int cas = 0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
k = 9;//最多能填9
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("Case #%d: So naive!\n",++cas);
continue;
}
if(!judge(sumrow))
flag = 1;
if(flag == 1)
{
printf("Case #%d: So naive!\n",++cas);
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("Case #%d: So young!\n",++cas);
else
{
printf("Case #%d: So simple!\n",++cas);
/* 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;
}
hdu 4975 A simple Gaussian elimination problem.(网络流,推断矩阵是否存在)的更多相关文章
- HDU 4975 A simple Gaussian elimination problem.
A simple Gaussian elimination problem. Time Limit: 1000ms Memory Limit: 65536KB This problem will be ...
- hdu - 4975 - A simple Gaussian elimination problem.(最大流量)
意甲冠军:要在N好M行和列以及列的数字矩阵和,每个元件的尺寸不超过9,询问是否有这样的矩阵,是独一无二的N(1 ≤ N ≤ 500) , M(1 ≤ M ≤ 500). 主题链接:http://acm ...
- hdu 4975 A simple Gaussian elimination problem 最大流+找环
原题链接 http://acm.hdu.edu.cn/showproblem.php?pid=4975 这是一道很裸的最大流,将每个点(i,j)看作是从Ri向Cj的一条容量为9的边,从源点除法连接每个 ...
- HDOJ 4975 A simple Gaussian elimination problem.
和HDOJ4888是一样的问题,最大流推断多解 1.把ISAP卡的根本出不来结果,仅仅能把全为0或者全为满流的给特判掉...... 2.在残量网络中找大于2的圈要用一种类似tarjian的方法从汇点開 ...
- A simple Gaussian elimination problem.(hdu4975)网络流+最大流
A simple Gaussian elimination problem. Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65 ...
- hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)
这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...
- A simple Gaussian elimination problem.
hdu4975:http://acm.hdu.edu.cn/showproblem.php?pid=4975 题意:给你一个n*m的矩阵,矩阵中的元素都是0--9,现在给你这个矩阵的每一行和每一列的和 ...
- hdu4975 A simple Gaussian elimination problem.(最大流+判环)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975 题意:和hdu4888基本一样( http://www.cnblogs.com/a-clown/ ...
- hdu 4972 A simple dynamic programming problem(高效)
pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...
随机推荐
- HDOJ 1003 Max Sum(线性dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 思路分析:该问题为最大连续子段和问题,使用动态规划求解: 1)最优子结构:假设数组为A[0, 1 ...
- windows上放弃使用PyGTK
windows上放弃使用PyGTK - riag的专栏 - 博客频道 - CSDN.NET windows上放弃使用PyGTK 分类: python 2010-03-31 16:47 1054人阅读 ...
- 碰撞缓冲效果的导航条 js
- [译]Stairway to Integration Services Level 16 – Flexible Source Locations (多文件导入)
介绍 在本文中我们将利用SSIS参数,变量 以及 Foreach Loop Container 从多个源动态导入数据. 开始前我们先下载一些数据.WeatherData_Dec08_Apr09.zip ...
- Cannot mix incompatible Qt library (version 0x40801) with this library (version 0x40804)
安装EMAN2(单颗粒重构的软件)之后,运行e2projectmanager.py来启动程序出现了这个错误. 去网上找了一下,发现一个靠谱的方案,这个问题出现是由于EMAN2这个程序自带了Qt的库,而 ...
- BZOJ 1230: [Usaco2008 Nov]lites 开关灯( 线段树 )
线段树.. --------------------------------------------------------------------------------- #include< ...
- JDK和JRE的差异和区别
来源:http://docs.oracle.com/javase/7/docs/
- Shell Script(1)----variable compare
PS:在学习python的时间里,抽空复习自己学习的Linux下的shell脚本知识点 1.数据类型 学习一门语言,比较关心其数据的表示方式,以及数据的类型,这里首先看一个bash shell的脚本 ...
- 如何用一个语句判断一个整数是不是二的整数次幂——从一道简单的面试题浅谈C语言的类型提升(type promotion)
最近招聘季,看JULY大哥的面试100题时,碰到这么一个扩展问题: 如何用一个语句判断一个整数是不是二的整数次幂?(此题在编程之美也有) easy, 2的整数次幂的二进制形式只有一个1,只要用i和i- ...
- Web Api Route 注册要放在 Mvc Route 注册前
今天想研究一下Web Api,写了一个测试Api,打开网站后浏览一下,可是却提示找不到方法,刚开始以为哪里配置错了,可找了半天也没见. 因为我是在一个现有Mvc站点做的Demo,所以打算新建一个Mvc ...