求网络最大流,如果最大流量等于所有单位人数之和,则存在解,否则无解。对于每个单位,从X集合对应点出发的所有满流边指向的Y集合的顶点就是该单位人员的安排情况(一个可行解)。
这个题是多解也就是求出来的只是一个可行解。。。。所以测数据可能有的会错。。。。简单题。。。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define inf 1<<30 #define N 100000 #define cc(m,v) memset(m,v,sizeof(m)) struct node{ int u,v,f,next; }edge[N]; int head[1000],p,lev[1000],cur[1000]; int que[N]; void ainit(){ p=0,cc(head,-1); } bool bfs(int s,int t){ int i,u,v,qin=0,qout=0; cc(lev,-1),lev[s]=0,que[qin++]=s; while(qout!=qin){ u=que[qout++]; for(i=head[u];i!=-1;i=edge[i].next) if(edge[i].f>0 && lev[v=edge[i].v]==-1){ lev[v]=lev[u]+1,que[qin++]=v; if(v==t) return 1; } } return 0; } int dinic(int s,int t){ int i,k,u,qin,f; int flow=0; while(bfs(s,t)){ memcpy(cur,head,sizeof(head)); u=s,qin=0; while(1){ if(u==t){ for(k=0,f=inf;k<qin;k++) if(edge[que[k]].f<f) f=edge[que[i=k]].f; for(k=0;k<qin;k++) edge[que[k]].f-=f,edge[que[k]^1].f+=f; flow+=f,u=edge[que[qin=i]].u; } for(i=cur[u];cur[u]!=-1;i=cur[u]=edge[cur[u]].next) if(edge[i].f>0 && lev[u]+1==lev[edge[i].v]) break; if(cur[u]!=-1) que[qin++]=cur[u],u=edge[cur[u]].v; else{ if(qin==0) break; lev[u]=-1,u=edge[que[--qin]].u; } } } return flow; } void addedge(int u,int v,int f){ edge[p].u=u,edge[p].v=v,edge[p].f=f,edge[p].next=head[u],head[u]=p++; edge[p].u=v,edge[p].v=u,edge[p].f=0,edge[p].next=head[v],head[v]=p++; } int main(){ int n,m,i,u,s,t,j,sum,sum1; while(scanf("%d%d",&m,&n)!=-1 && m){ ainit(); s=0,t=n+m+1,sum=0,sum1=0; for(i=1;i<=m;i++){ scanf("%d",&u); addedge(s,i,u); sum+=u; } for(i=m+1;i<t;i++){ scanf("%d",&u); addedge(i,t,u); sum1+=u; } for(i=1;i<=m;i++) for(j=t-1;j>=1+m;j--) addedge(i,j,1); if(sum<=sum1 && dinic(s,t)==sum){ printf("1\n"); for(i=1;i<=m;i++){ for(j=head[i];j!=-1;j=edge[j].next) if(edge[j].f==0 && edge[j].v!=0) printf("%d ",edge[j].v-m); printf("\n"); } }else printf("0\n"); } return 0; }