2 2 4 4 2 4 2 4 2 2 2 2 5 0 5 4 1 4 3 9 1 2 3 3
Not Unique Impossible Unique 1 2 3 3
已知一个矩阵,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; }