hdu 4888
网络流建模,建模不难,难在找环;
#include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<cstring> #define inf 1<<30 #define maxn 2100 using namespace std; struct edge { int from,to,cap,flow; edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow) {} }; struct dinic { int n,m,s,t; vector<edge>edges; vector<int>g[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; bool ishuan[maxn]; int jie[550][550]; void init(int n) { this->n=n; for(int i=0; i<n; i++) g[i].clear(); edges.clear(); memset(d,0,sizeof d); memset(cur,0,sizeof cur); } void addedge(int from,int to,int cap) { edges.push_back(edge(from,to,cap,0)); edges.push_back(edge(to,from,0,0)); m=edges.size(); g[from].push_back(m-2); g[to].push_back(m-1); } queue<int >q; bool bfs() { memset(vis,0,sizeof vis); while(!q.empty()) q.pop(); q.push(s); d[s]=0; vis[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); for(int i=0; i<g[x].size(); i++) { edge& e=edges[g[x][i]]; if(!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; d[e.to]=d[x]+1; q.push(e.to); } } } return vis[t]; } int dfs(int x,int a) { if(x==t||a==0)return a; int flow=0,f; for(int &i=cur[x]; i<g[x].size(); i++) { edge& e=edges[g[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[g[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int maxflow(int s,int t) { this->s=s; this->t=t; int flow=0; while(bfs()) { memset(cur,0,sizeof cur); flow+=dfs(s,inf); } return flow; } bool panhuan(int v,int f) { if(ishuan[v])return 1; ishuan[v]=1; for(int i=0;i<g[v].size();i++) { if(g[v][i]==(f^1))continue; int tmp=g[v][i]; if(edges[tmp].to==t||edges[tmp].to==s)continue; if(edges[tmp].cap-edges[tmp].flow>0) { if(panhuan(edges[tmp].to,tmp))return 1; } } ishuan[v]=0; return 0; } bool haofang(int x) { memset(ishuan,0,sizeof ishuan); for(int i=1; i<=x; i++) { if(panhuan(i,-1))return 1; } return 0; } void getans(int x,int y) { for(int i=0;i<edges.size();i++) { if(edges[i].cap&&edges[i].from>0&&edges[i].from<=x) { jie[edges[i].from][edges[i].to-x]=edges[i].flow; } } } }; int hang[550]; int lie[550]; dinic solve; int main() { int n,m,k; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { int sum_hang=0,sum_lie=0; for(int i=1; i<=n; i++) { scanf("%d",&hang[i]); sum_hang+=hang[i]; } for(int i=1; i<=m; i++) { scanf("%d",&lie[i]); sum_lie+=lie[i]; } if(sum_hang!=sum_lie) { puts("Impossible"); continue; } solve.init(n+m+2); solve.s=0; solve.t=n+m+1; for(int i=1;i<=n;i++) { solve.addedge(solve.s,i,hang[i]); for(int j=1;j<=m;j++) solve.addedge(i,j+n,k); } for(int i=1;i<=m;i++) solve.addedge(i+n,solve.t,lie[i]); int ans=solve.maxflow(solve.s,solve.t); if(ans!=sum_hang) puts("Impossible"); else { if(solve.haofang(n)) puts("Not Unique"); else { puts("Unique"); solve.getans(n,m); for(int i=1;i<=n;i++) { for(int j=1;j<m;j++) printf("%d ",solve.jie[i][j]); printf("%d\n",solve.jie[i][m]); } } } } return 0; }