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 ...
随机推荐
- Noip2007提高组总结
两道基础题,后两题比较麻烦,算法想出来后,还是一些细枝末节的问题,需要特别注意,感觉Noip的题目质量还是挺高的,每做一套,都感觉会有大大小小不同的收获,就要月考了,最后把07年的题目总结一下,算是这 ...
- Django的TemplateResponse
def my_render_callback(response): return response from django.template.response import TemplateRespo ...
- Objective-c 类接口 (@interface) (类定义)
在Objective-c中如何定义一个类呢?我们可以使用下面的格式进行表示: @interface 类名:父类名{ 变量定义; } 方法定义: @end; 下面给出一个实例: @interface P ...
- Redis初始化配置及增删改查
package com.calc.tools import redis.clients.jedis.JedisPool import redis.clients.jedis.Jedis import ...
- lightOJ 1047 Neighbor House (DP)
lightOJ 1047 Neighbor House (DP) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87730# ...
- opencv第一站:配置opencv环境(2015-12-12)
今天论坛申请的书< OpenCV 计算机视觉编程攻略(中国工信出版社)>到了,准备研究研究机器视觉. 晚上安装了 vc2008 及 opencv 最新版 3.0.0,试了各种配置都是错误提 ...
- uml笔记
把进度放在好了: 活动图与业务流程 对业务流程支持的主要图形就是活动图,活动图的主要目的在陈述活动与活动之间流程控制的转移.
- myeclipse 8.6 插件安装之SVN
在这里我要说明一点,myEclipse 8.6的插件安装和之前的版本可能会有一些区别,下面是SVN插件的安装: 1.从官网下载site-1.6.13.zip文件,网址是:subclipse.tigri ...
- JavaScript基础知识----六道有趣的Js基础题以及解答
题目: 1.找出数字数组中最大的元素(使用Math.max函数)2.转化一个数字数组为function数组(每个function都弹出相应的数字)3.给object数组进行排序(排序条件是每个元素对象 ...
- Android 开发笔记 “广播组件使用”
在Activity中,注册广播的一个Demo. 总共分3步 第一步:定义一个BroadcastReceiver广播接收类: private BroadcastReceiver mBroadcastRe ...