zoukankan      html  css  js  c++  java
  • 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;
    }
    


  • 相关阅读:
    git拉取线上新分支拉不下来
    contenteditable属性,让div也可编辑
    给2021做一个小结
    http协议相关面试题
    C# 相对路径 系统路径
    开源数据库全接触-MongoDB,Cassandra,Hypertable,CouchDB,Redis,HBase,Voldemort 等简介
    WebForms,MVC和网页的OAuth / OpenID的支持
    HTTP head 详解
    CAB 文件注册及内部INF 文件说明
    【ECJTU_ACM 11级队员2012年暑假训练赛(8) I Lucky Division】
  • 原文地址:https://www.cnblogs.com/yxwkf/p/3921671.html
Copyright © 2011-2022 走看看