swust1740: 圆桌问题

来源:互联网 发布:初级程序员考什么语言 编辑:程序博客网 时间:2024/05/02 00:29

链接:http://www.oj.swust.edu.cn/problem/show/1740

题意:中文题。

分析:网络流24题第五题。模型比较基础,从超级源连边到每个代表团,容量为他们的人数,每个桌子连一条边到超级汇,每个代表团都连一条边到每张桌子容量为1。那么最大流等于总人数就是yes啦。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<sstream>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=455;const int MAX=1000000100;const int mod=100000000;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=998244353;const int INF=1000000010;const double pi=acos(-1.0);typedef double db;typedef unsigned long long ull;int tot,u[N],v[N*N],cap[N*N],flow[N*N],pre[N*N];void add(int a,int b,int c,int f) {    v[tot]=b;cap[tot]=c;flow[tot]=f;pre[tot]=u[a];u[a]=tot++;}bool q[N];int d[N],dis[N],head[N];bool bfs(int a,int b) {    int i,l=1,r=1;    memset(q,0,sizeof(q));    d[1]=a;q[a]=1;dis[a]=0;    for (;l<=r;l++)        for (i=u[d[l]];i!=-1;i=pre[i])        if (!q[v[i]]&&cap[i]>flow[i]) q[v[i]]=1,d[++r]=v[i],dis[v[i]]=dis[d[l]]+1;    return q[b];}int dfs(int a,int b,int en) {    if (a==en||b==0) return b;    int ret=0,f;    for (int& i=u[a];i!=-1;i=pre[i])    if (dis[v[i]]==dis[a]+1&&(f=dfs(v[i],min(b,cap[i]-flow[i]),en))>0) {        flow[i]+=f;flow[i^1]-=f;        b-=f;ret+=f;        if (b==0) break ;    }    return ret;}int main(){    int a,i,j,n,m,sum=0,ans=0;    scanf("%d%d", &n, &m);    tot=sum=ans=0;    memset(u,-1,sizeof(u));    for (i=1;i<=n;i++) {        scanf("%d", &a);sum+=a;        add(0,i,a,0);add(i,0,0,0);    }    for (i=1;i<=m;i++) {        scanf("%d", &a);        add(i+n,n+m+1,a,0);add(n+m+1,i+n,0,0);    }    for (i=1;i<=n;i++)        for (j=1;j<=m;j++) add(i,j+n,1,0),add(j+n,i,0,0);    for (i=0;i<=n+m+1;i++) head[i]=u[i];    while (bfs(0,n+m+1)) {        ans+=dfs(0,INF,n+m+1);        for (i=0;i<=n+m+1;i++) u[i]=head[i];    }    if (ans==sum) {        printf("1\n");        for (i=1;i<=n;i++) {            for (j=u[i];j!=-1;j=pre[j])            if (flow[j]==cap[j]&&v[j]!=0) printf("%d ", v[j]-n);            printf("\n");        }    } else printf("0\n");    return 0;}


0 0
原创粉丝点击