• 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;
    }
    


  • 相关阅读:
    <contextparam>与<initparam>的区别与作用
    Eclipse中的条件断点
    通过ContentResolver调用系统URI实现的通讯录示例
    Spring中ApplicationContext加载机制和配置初始化
    Java常见笔试、面试题目深度剖析
    加载/WEBINF/applicationContext.xml的解决方法
    Spring ClassPathXmlApplicationContext和FileSystemXmlApplicationContext
    改变MyEclipse默认编码方式
    怎么把100多个EXCEL文件合并成一个
    1.Python简介
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3921671.html
Copyright © 2020-2023  润新知