HDU 4888

HDU 4888

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

Redraw Beautiful Drawings

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1993    Accepted Submission(s): 446

Problem Description
Alice and Bob are playing together. Alice is crazy about art and she has visited many museums around the world. She has a good memory and she can remember all drawings she has seen.

Today Alice designs a game using these drawings in her memory. First, she matches K+1 colors appears in the picture to K+1 different integers(from 0 to K). After that, she slices the drawing into grids and there are N rows and M columns. Each grid has an integer on it(from 0 to K) representing the color on the corresponding position in the original drawing. Alice wants to share the wonderful drawings with Bob and she tells Bob the size of the drawing, the number of different colors, and the sum of integers on each row and each column. Bob has to redraw the drawing with Alice’s information. Unfortunately, somtimes, the information Alice offers is wrong because of Alice’s poor math. And sometimes, Bob can work out multiple different drawings using the information Alice provides. Bob gets confused and he needs your help. You have to tell Bob if Alice’s information is right and if her information is right you should also tell Bob whether he can get a unique drawing.

 

Input
The input contains mutiple testcases.

For each testcase, the first line contains three integers N(1 ≤ N ≤ 400) , M(1 ≤ M ≤ 400) and K(1 ≤ K ≤ 40).

N integers are given in the second line representing the sum of N rows.

M integers are given in the third line representing the sum of M columns.

The input is terminated by EOF.

 

Output
For each testcase, if there is no solution for Bob, output “Impossible” in one line(without the quotation mark); if there is only one solution for Bob, output “Unique” in one line(without the quotation mark) and output an N * M matrix in the following N lines representing Bob’s unique solution; if there are many ways for Bob to redraw the drawing, output “Not Unique” in one line(without the quotation mark).
 

Sample Input
   
   
2 2 4 4 2 4 2 4 2 2 2 2 5 0 5 4 1 4 3 9 1 2 3 3

 

Sample Output
   
   
Not Unique Impossible Unique 1 2 3 3

 

Author
Fudan University
 

Source

已知一个矩阵,n行m列。已知每一行,每一列的和,推断是否存在这种矩阵,而且推断是否唯一。

非常裸的最大流模型,前面的部分非常水,关键是,最大流判环部分有点纠结。

代码:

/* ***********************************************
Author :rabbit
Created Time :2014/8/4 18:18:37
File Name :11.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=20100;
const int maxm=1002000;
struct Edge{
	int next,to,cap;
	Edge(){};
	Edge(int _next,int _to,int _cap){
		next=_next;to=_to;cap=_cap;
	}
}edge[maxm];
int head[maxn],tol,dep[maxn],gap[maxn];
void addedge(int u,int v,int flow){
    edge[tol]=Edge(head[u],v,flow);head[u]=tol++;
    edge[tol]=Edge(head[v],u,0);head[v]=tol++;
}
void bfs(int start,int end){
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0]++;int front=0,rear=0,Q[maxn];
    dep[end]=0;Q[rear++]=end;
    while(front!=rear){
        int u=Q[front++];
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;if(dep[v]==-1)
                Q[rear++]=v,dep[v]=dep[u]+1,gap[dep[v]]++;
        }
    }
}
int cur[maxn],S[maxn];
int sap(int s,int t,int N){
	int res=0;bfs(s,t);
	int top=0,u=s,i;
	memcpy(cur,head,sizeof(head));
	while(dep[s]<N){
		if(u==t){
			int temp=INF,id;
		    for( i=0;i<top;i++)
			   if(temp>edge[S[i]].cap)
				   temp=edge[S[i]].cap,id=i;
		    for( i=0;i<top;i++)
			      edge[S[i]].cap-=temp,edge[S[i]^1].cap+=temp;
		    res+=temp;top=id;u=edge[S[top]^1].to;
		}
		if(u!=t&&gap[dep[u]-1]==0)break;
		for( i=cur[u];i!=-1;i=edge[i].next)
			if(edge[i].cap&&dep[u]==dep[edge[i].to]+1)break;
		if(i!=-1)cur[u]=i,S[top++]=i,u=edge[i].to;
		else{
			int MIN=N;
			for( i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap&&MIN>dep[edge[i].to])
					MIN=dep[edge[i].to],cur[u]=i;
			--gap[dep[u]];++gap[dep[u]=MIN+1];
			if(u!=s)u=edge[S[--top]^1].to;
		}
	}
	return res;
}
int hang[500],lie[500];
int flow[500][500],vis[maxn],m,n,k;
bool dfs(int u,int fa){
	if(vis[u])return 1;
	vis[u]=1;
	for(int i=head[u];i!=-1;i=edge[i].next){
		int v=edge[i].to;
		if(v==fa||v==0||v==n+m+1||edge[i].cap==0)continue;
		if(dfs(v,u))return 1;
	}
	vis[u]=0;
	return 0;
}
int main()
{
     freopen("1002.in","r",stdin);
     freopen("data.out","w",stdout);
	 while(~scanf("%d%d%d",&n,&m,&k)){
		 memset(head,-1,sizeof(head));tol=0;
		 int L=0,R=0;
		 for(int i=1;i<=n;i++)scanf("%d",&hang[i]),L+=hang[i];
		 for(int i=1;i<=m;i++)scanf("%d",&lie[i]),R+=lie[i];
		 if(L!=R){
			 puts("Impossible");continue;
		 }
		 for(int i=1;i<=n;i++)
			 addedge(0,i,hang[i]);
		 for(int i=1;i<=m;i++)
			 addedge(i+n,n+m+1,lie[i]);
		 for(int i=1;i<=n;i++)
			 for(int j=n+1;j<=n+m;j++)
				 addedge(i,j,k);
		 int ans=sap(0,n+m+1,m+n+100);
		 if(ans!=L){
			 puts("Impossible");continue;
		 }
		 int flag=0;
		 memset(vis,0,sizeof(vis));
		 for(int i=1;i<=n;i++)
			 if(dfs(i,-1)){
				 flag=1;break;
			 }
		 if(flag)puts("Not Unique");
		 else {
			 puts("Unique");
			 for(int i=1;i<=n;i++)
				 for(int j=head[i];j!=-1;j=edge[j].next){
					 int v=edge[j].to;
					 if(v>n&&v<=n+m)
						 flow[i][v-n]=k-edge[j].cap;
				 }
			 for(int i=1;i<=n;i++){
				 printf("%d",flow[i][1]);
				 for(int j=2;j<=m;j++)
					 printf(" %d",flow[i][j]);
				 puts("");
			 }
		 }
	 }
     return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118593.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Freemarker判断对象是否为空的用法

    Freemarker判断对象是否为空的用法注:https://blog.csdn.net/elladu/article/details/80393814freemark判断对象的属性&lt;#if(${blog.belongid==1})&gt;red&lt;/#if&gt;以上不对,应该是&lt;#if(blog.belongid==1)&gt;red&lt;/#if&gt;参考…

    2022年5月24日
    59
  • dhcp snooping option 82_dhcpsnooping的原理配置案例

    dhcp snooping option 82_dhcpsnooping的原理配置案例DHCPSnooping-option82relay的原理及实例一、采用DHCP服务的常见问题架设DHCP服务器可以为客户端自动分配IP地址、掩码、默认网关、DNS服务器等网络参数,简化了网络配置,提高了管理效率。但在DHCP服务的管理上存在一些问题,常见的有:●DHCPServer的冒充●DHCPServer的DOS,如DHCP耗竭●某些用户随便指定IP地址,造成IP地址冲突1、D…

    2022年10月15日
    2
  • OpenCV中的width与widthStep

    OpenCV中的width与widthStep1.在opencv中width表示的是图像的每行像素数,widthstep表示的是存储一行像素需要的字节数,位了快速读取数据,在opencv中一般使widthStep为4的倍数,从而实现字节的对齐,有利于提高运算速度。2.函数的原型为image->widthStep=(((image->width*image->nChannels*(image->depth&~IPL_DEPTH_SIGN)+7)/8)+align-1)&(~(alig

    2022年5月30日
    41
  • C# 远程唤醒(远程开机)

    C# 远程唤醒(远程开机)C#远程唤醒(远程开机)近日,小白要用到远程开机的功能,网上大多介绍的是MagicPacket的工具。实际上,此MagicPacket是AMD公司开发的,请在google.cn中搜索MagicPacketTechnology。原理上我们不用深入,实现上是发一个BroadCast包,包的内容包括以下数据就可以了。FFFFFFFFFFFF,6个FF是数据的开始,紧跟着16次

    2022年5月24日
    181
  • ❤️Jenkins从零到壹❤️ 两万字Jenkins教程大全汇总(JAVA 小虚竹 建议收藏)

    ❤️Jenkins从零到壹❤️ 两万字Jenkins教程大全汇总(JAVA 小虚竹 建议收藏)❤️Jenkins从零到壹❤️两万字Jenkins教程大全汇总(JAVAjava小虚竹)

    2022年5月14日
    42
  • Java入门基础学习总结[通俗易懂]

    Java入门基础学习总结[通俗易懂]基础(Basics)打开CMD的方式:1.开始+系统+命令提示符2.Win键+R输入cmd打开控制台(推荐使用)3.在任意的文件夹下面,按住shift键+鼠标右键点击,在此处打开命令行窗口4.资源管理器的地址栏前面加上cmd一个空格路径常用的Dos命令#盘符切换D:冒号需用英文模式#查看当前目录下的所有文件dir#切换目录cdchangedirectorycd.. 返回上级目录#清理屏幕cls(clearscreen)#退出终端exit#查看电脑的i

    2022年7月8日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号