标签:des style blog http color java os strong
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
2014-07-31 01:22:46 | Accepted | 4888 | 625MS | 5244K | 3493 B | G++ |
题目大意:
求一个矩阵,给出矩阵每行和每列的和,矩阵中数字[0,K]
若矩阵唯一,输出Unique及矩阵
若不唯一,输出Not Unique
若不存在,输出impossible
解题方法:
增加源点汇点,建立网络流,
源点->i行 容量为行和
i行->j列 容量为k
j列->汇点 容量为列和
容易得到,
若最大流<sum,则不存在
否则存在,
接下来转换为判断流是否唯一的问题上,即中间的流是否唯一,即中间的流能否相互转移,从增广路径的思想上来看,只需存在一个环,则可以转换流,故存在多解。问题即判断残余网络上是否存在环。
第一次用了下之前的dinic模板,果然省事许多,可惜判断矩阵是否唯一的dfs写超时了,折腾许久,不过也终究搞定了。
#include <cstdio> #include <cstring> #define N 808 #define M 640008 int d[N],be[N]; int s,t,n,m,k,z,tot,all; bool v[N]; struct Edge{ int x,y,c,next; }e[M*2]; void add(int x, int y, int z)//需保证相反边第一个为偶数 { e[all].x=x; e[all].y=y; e[all].c=z; e[all].next=be[x]; be[x]=all; all++; e[all].x=y; e[all].y=x; e[all].c=0; e[all].next=be[y]; be[y]=all; all++; } bool BFS(int s, int t) { memset(d,-1,sizeof(d)); int head=0,tail=0,q[N]; q[++tail]=s; d[s]=0; while(head<tail){ int cur=q[++head]; for(int i=be[cur]; i!=-1; i=e[i].next) if(e[i].c>0 && d[e[i].y]==-1){ d[e[i].y]=d[cur]+1; q[++tail]=e[i].y; } } return d[t]!=-1; } int Dinic(int s, int t)//防止爆栈 用stack模拟递归 { int ans=0; int stack[N],top; int begin[N]; while(BFS(s,t)) { memcpy(begin,be,sizeof(be)); int cur=s; top=0;//dfs开始 清空栈 while(1) { if(cur==t){ int minc=1000000000,mini; for(int i=0; i<top; i++) if(minc>e[stack[i]].c) { minc=e[stack[i]].c; mini=i;//以便之后回到这继续增广 } for(int i=0; i<top; i++) { e[stack[i]].c-=minc; e[stack[i]^1].c+=minc;//第一个二进制取反 即取相反边 } ans+=minc; top=mini; cur=e[stack[mini]].x; } for(int i=begin[cur]; i!=-1; begin[cur]=i=e[begin[cur]].next) if(e[i].c>0 && d[e[i].y]==d[e[i].x]+1) break; if(begin[cur]!=-1){ stack[top++]=begin[cur]; cur=e[begin[cur]].y; }else{ if(top==0) break; d[cur]=-1;//当前节点不在增广路中 删除 cur=e[stack[--top]].x;//回溯 } } } return ans; } bool dfs(int cur, int fa) { if(v[cur]) return 1; v[cur]=1; for(int i=be[cur]; i!=-1; i=e[i].next) if(e[i].c>0 && e[i].y!=fa && dfs(e[i].y,cur)) return 1; v[cur]=0; return 0; } bool check() { memset(v,0,sizeof(v)); for(int i=1; i<=n; i++) if(dfs(i,-1)) return 1; return 0; } void print() { int ans[N]; for(int i=1; i<=n; i++){ for(int j=be[i]; j!=-1; j=e[j].next) ans[e[j].y]=e[j].c; for(int j=n+1; j<=n+m; j++) if(j!=n+m) printf("%d ",k-ans[j]); else printf("%d\n",k-ans[j]); } } int main() { while(scanf("%d%d%d",&n,&m,&k)!=EOF) { s=n+m+1; t=n+m+2; tot=0; all=0; int ans=0; memset(be,-1,sizeof(be)); for(int i=0; i<n; i++){ scanf("%d",&z); add(s,++tot,z); ans+=z; } for(int i=0; i<m; i++){ scanf("%d",&z); add(++tot,t,z); } for(int i=1; i<=n; i++) for(int j=n+1; j<=n+m; j++) add(i,j,k); ans-=Dinic(s,t); if(ans!=0) printf("Impossible\n"); else { if(check()) printf("Not Unique\n"); else{ printf("Unique\n"); print(); } } } return 0; }
HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3),布布扣,bubuko.com
HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
标签:des style blog http color java os strong
原文地址:http://www.cnblogs.com/Mathics/p/3879757.html