hdu 4888 Redraw Beautiful Drawings 2014多校三补题 网络流
2014-08-22 21:42
417 查看
题目链接:hdu 4888
给定一个N*M的矩阵,已知每行和以及每列和,每个元素(大于等于0)的上限值K,问这样的矩阵是否存在,若存在,判断是否唯一,唯一则输出
网络流,从源点向行带表的点建边,流量为行和,列代表的边向汇点建边,流量为列和,每行向每列建边,流量为K,求源点到汇点的最大流,若是满流,则说明矩阵存在。然后判断残留网络是否存在环,若存在则说明有多解
给定一个N*M的矩阵,已知每行和以及每列和,每个元素(大于等于0)的上限值K,问这样的矩阵是否存在,若存在,判断是否唯一,唯一则输出
网络流,从源点向行带表的点建边,流量为行和,列代表的边向汇点建边,流量为列和,每行向每列建边,流量为K,求源点到汇点的最大流,若是满流,则说明矩阵存在。然后判断残留网络是否存在环,若存在则说明有多解
/****************************************************** * File Name: 4888.cpp * Author: kojimai * Creater Time:2014年08月22日 星期五 00时58分29秒 ******************************************************/ /* *网络流,求最大流是否满流 *然后判断残留网络是否存在环 */ #include<queue> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; int n,m,K; #define FFF 404 int row[FFF],col[FFF]; int map[FFF][FFF]; struct node { int u,v,f,next; }p[400010]; int first[900],e,cur[900],dis[900],que[2100]; void addedge(int u,int v,int c) { p[e].u=u;p[e].v=v;p[e].f=c;p[e].next=first[u];first[u]=e++; p[e].u=v;p[e].v=u;p[e].f=0;p[e].next=first[v];first[v]=e++; } bool bfs(int s,int t)//找增广路径 { memset(dis,-1,sizeof(dis)); dis[s]=0; queue<int> q; q.push(s); while(!q.empty()) { int now=q.front();q.pop(); for(int k=first[now];~k;k=p[k].next) { if(p[k].f>0&&dis[p[k].v]==-1) { dis[p[k].v]=dis[now]+1; if(p[k].v==t) return true; q.push(p[k].v); } } } return false; } int dinic(int s,int t)//dinic求最大流 { //cout<<"s="<<s<<" t="<<t<<endl; int ans=0; while(bfs(s,t)) { memcpy(cur,first,sizeof(first)); int now=s,tail=0; while(true) { int k; if(now==t) { int flow=23333333,fir; for(int i=0;i<tail;i++) { if(p[que[i]].f<flow) { fir=i; flow=p[que[i]].f; } } for(int i=0;i<tail;i++) { p[que[i]].f-=flow; p[que[i]^1].f+=flow; } ans+=flow; tail=fir; now=p[que[fir]].u; } for(k=cur[now];~k;cur[now]=k=p[k].next) { if(p[k].f&&dis[now]+1==dis[p[k].v]) break; } if(cur[now]!=-1) { que[tail++]=cur[now]; now=p[cur[now]].v; } else { if(tail==0) break; dis[now]=-1; now=p[que[--tail]].u; } } } return ans; } int vis[FFF*2]; /*int dfn[FFF*2],low[FFF*2],c[FFF*2],snum,dnum,stack[FFF*2]; bool tarjan(int s,int last)//tarjan找环不可行,因为不能算两点的环,容易出错 { dfn[s]=low[s]=dnum++; stack[snum++]=s;vis[s]=true; for(int k=first[s];k!=-1;k=p[k].next) { //cout<<" s="<<s<<" k="<<k<<" v="<<p[k].v<<" f="<<p[k].f<<endl; if(p[k].f>0&&k!=last) { if(!dfn[p[k].v]) { if(tarjan(p[k].v,s)) return true; low[s]=min(low[s],low[p[k].v]); } else if(vis[p[k].v]) { low[s]=min(low[s],dfn[p[k].v]); } } } //cout<<"s="<<s<<" low="<<low[s]<<" dfn="<<dfn[s]<<endl; if(low[s]==dfn[s]) { int y=stack[--snum]; //cout<<"s="<<s<<" y="<<y<<endl; vis[y]=false; if(y!=s) return true; } return false; }*/ bool dfs(int s,int last)//找环 { for(int k=first[s];~k;k=p[k].next) { if(p[k].v==last)continue; if(p[k].f) { if(vis[p[k].v])return true; vis[p[k].v]=true; if(dfs(p[k].v,s))return true; vis[p[k].v]=false; } } return false; } void out() { printf("Unique\n"); memset(map,0,sizeof(map)); for(int i=1;i<=n;i++) { for(int k=first[i];~k;k=p[k].next) { if(p[k].v>n&&p[k].v<=n+m) map[i][p[k].v-n]=K-p[k].f;//用流量上限减去残留网络的值,即为当前的流量 } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(j==m) printf("%d\n",map[i][j]); else printf("%d ",map[i][j]); } } return; } int main() { //freopen("out.out","w",stdout); while(~scanf("%d%d%d",&n,&m,&K)) { int alla=0,allb=0; for(int i=1;i<=n;i++) { scanf("%d",&row[i]); alla+=row[i]; } for(int i=1;i<=m;i++) { scanf("%d",&col[i]); allb+=col[i]; } if(alla!=allb) printf("Impossible\n"); else { e=0; memset(first,-1,sizeof(first)); for(int i=1;i<=n;i++) { addedge(0,i,row[i]); } for(int i=1;i<=m;i++) addedge(i+n,n+m+1,col[i]); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) addedge(i,j+n,K); } int sum=dinic(0,n+m+1); if(sum!=alla) printf("Impossible\n"); else { //snum=1;dnum=1; memset(vis,false,sizeof(vis)); bool flag=false; //memset(dfn,0,sizeof(dfn)); //memset(low,0,sizeof(low)); for(int i=n;i>=1&&!flag;i--) { if(!vis[i]) flag=dfs(i,-1); } if(flag) printf("Not Unique\n"); else out(); } } } return 0; }
相关文章推荐
- hdu 4888 2014多校第三场1002 Redraw Beautiful Drawings 网络流
- hdu 4888 2014多校第三场1002 Redraw Beautiful Drawings 网络流
- HDU 4888 Redraw Beautiful Drawings 网络流 建图
- HDU 4888 Redraw Beautiful Drawings(网络流求矩阵的解)
- HDU 4888 Redraw Beautiful Drawings 网络流(矩阵模型)
- 【HDU】4888 Redraw Beautiful Drawings 网络流【判断解是否唯一】
- HDU 4888 (杭电多校#3)Redraw Beautiful Drawings(网络流之最大流)
- HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
- HDU 4888 Redraw Beautiful Drawings (2014-多校3-1002,最大流,判最大流有多解)
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
- Hdu-4888 Redraw Beautiful Drawings 网络流
- hdu 4888 Redraw Beautiful Drawings 网络流+搜索
- HDU 4888 Redraw Beautiful Drawings 网络流 建图
- hdu 4888 Redraw Beautiful Drawings(最大流)
- 【网络流】 HDOJ 4888 Redraw Beautiful Drawings
- HDU 4888 Redraw Beautiful Drawings 最大流(唯一性)
- hdu 4888 Redraw Beautiful Drawings(Dinic最大流+判断有没有环)
- hdu 4888 Redraw Beautiful Drawings (最大流)
- HDU-4888-Redraw Beautiful Drawings
- hdu 4975 A simple Gaussian elimination problem. 2014多校十 网络流