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 ...
随机推荐
- hdu1715 大菲波数
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1715 Problem ...
- 偶然碰到的Win7 64位下CHM 的问题解决
最近下了几个沪江资料,都是chm格式的,但是在win7 64位下,都显示不了里面的音频和视频flash之类的控件,虽然可以通过源文件的方式打开视频文件,但是很麻烦. 网上似乎碰到的人也不是很多, ...
- srm 534
250 Description 给你一个1*n的棋盘.两人轮流行动,每一个人能够把"o"向右移动到空格子.或者跨越连续两个"o"到空格子. 一个"o& ...
- c#Winform程序的toolStripButton自己定义背景应用演示样例源代码
C# Winform程序的toolStrip中toolStripButton的背景是蓝色的,怎样改变背景及边框的颜色和样式呢? 实现此功能须要重写toolStripButton的Paint方法 这里仅 ...
- sass基本语法
sass是一种基于ruby语言开发的CSS预处理器.它可以使用变量,嵌套,混入,继承,运算,函数等编程语言具有的特性进行CSS的开发,使得CSS的开发变得简单粗暴清晰可维护. sass有两种后缀文件格 ...
- VS快捷键简单记录
代码上下移动行:Alt+上下键 跳转相等大括号:Ctrl+]
- 专门针对初学者的Node.js教程
转载原文:http://www.csdn.net/article/2013-08-28/2816731-absolute-beginners-guide-to-nodejs Node.js的教程并不缺 ...
- eclipse修改java代码后报错: java.lang.OutOfMemoryError: PermGen space
由于在eclipse中运行项目后,我们又重新修改了某个java类,导致tomcat会重新加载这个项目所有的class.jar,多次加载后由于分配的存储空间有限,就导致了:java.lang.OutOf ...
- ppt类似工具AxeFile使用心得
一个所谓的傻瓜式过渡效果自动生成工具.定义好展示窗口大小,加入时序.所谓的闪烁效果,也是相当的滑稽. 是一个非专业的简单的快速PPT工具. 但是体现的确是扁平化的设计思路,很值得深思. ------ ...
- 使用R进行相关性分析
基于R进行相关性分析 一.相关性矩阵计算: [1] 加载数据: >data = read.csv("231-6057_2016-04-05-ZX_WD_2.csv",head ...