标签:des style http color io os ar java for
最大流判断多解
建图:
源点连接到每一个代表行的节点容量为行总和,每一个代表列的节点连接到汇点容量为列总和,行和列之间互相连接容量为Limit
多解:
做一遍ISAP后,在残量图上DFS看能否找到点数大于2的环即可
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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1000;
const int maxm=1001000;
const int INF=0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow;
}edge[maxm];
int Size,Adj[maxn];
int gap[maxn],dep[maxn],pre[maxn],cur[maxn];
void init()
{
Size=0; memset(Adj,-1,sizeof(Adj));
}
void addedge(int u,int v,int w,int rw=0)
{
edge[Size].to=v; edge[Size].cap=w; edge[Size].next=Adj[u];
edge[Size].flow=0;Adj[u]=Size++;
edge[Size].to=u; edge[Size].cap=rw; edge[Size].next=Adj[v];
edge[Size].flow=0;Adj[v]=Size++;
}
int sap(int start,int end,int N)
{
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,Adj,sizeof(Adj));
int u=start;
pre[u]=-1; gap[0]=N;
int ans=0;
while(dep[start]<N)
{
if(u==end)
{
int Min=INF;
for(int i=pre[u];~i;i=pre[edge[i^1].to])
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
for(int i=pre[u];~i;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
}
u=start;
ans+=Min;
continue;
}
bool flag=false;
int v;
for(int i=cur[u];~i;i=edge[i].next)
{
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
{
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag)
{
u=v; continue;
}
int Min=N;
for(int i=Adj[u];~i;i=edge[i].next)
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
{
Min=dep[edge[i].to];
cur[u]=i;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u]=Min+1;
gap[dep[u]]++;
if(u!=start) u=edge[pre[u]^1].to;
}
return ans;
}
int n,m,limit;
int a[maxn],b[maxn];
int id[maxn][maxn];
bool vis[maxn];
bool dfs(int u,int pre)
{
if(vis[u]) return true;
vis[u]=true;
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].flow>=edge[i].cap) continue;
if(v==pre) continue;
if(dfs(v,u)) return true;
}
vis[u]=false;
return false;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&limit)!=EOF)
{
init();
int sum1=0,sum2=0;
for(int i=1;i<=n;i++) scanf("%d",a+i),sum1+=a[i];
for(int i=1;i<=m;i++) scanf("%d",b+i),sum2+=b[i];
if(sum1!=sum2)
{
puts("Impossible");
continue;
}
/**************build graph *****************/
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
id[i][j]=Size;
addedge(i,n+j,limit);
}
for(int i=1;i<=n;i++)
addedge(0,i,a[i]);
for(int i=1;i<=m;i++)
addedge(n+i,n+m+1,b[i]);
/**************build graph *****************/
int MaxFlow=sap(0,n+m+1,n+m+1+2);
//cout<<"MaxFlow: "<<MaxFlow<<endl;
if(MaxFlow!=sum1)
{
puts("Impossible");
continue;
}
else
{
memset(vis,0,sizeof(vis));
bool flag=false;
for(int i=1;i<=n&&!flag;i++)
if(dfs(i,i)) flag=true;
if(flag)
{
puts("Not Unique");
continue;
}
puts("Unique");
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
printf("%d%c",edge[id[i][j]].flow,(j==m)?10:32);
}
}
}
return 0;
}
HDOJ 4888 Redraw Beautiful Drawings
标签:des style http color io os ar java for
原文地址:http://blog.csdn.net/ck_boss/article/details/39942313