[网络流24题-7]圆桌问题

圆桌问题

就是比较裸的一个网络流qwq

直接建源点汇点

源点连单位流量Ci 桌子连汇点流量Ri 单位桌子两两连边流量为1限流就可以了

然后输出方案就看一下流了这条边就是坐了这个桌子就吼了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define inf 20021225
#define maxn 100100
using namespace std;

struct edge{int to,lt,f;}e[maxn<<4];
int in[maxn],nn,cnt=1,s,t,dep[maxn];
queue<int> que;
void add(int x,int y,int f)
{
    e[++cnt].to=y;e[cnt].lt=in[x];in[x]=cnt;e[cnt].f=f;
    e[++cnt].to=x;e[cnt].lt=in[y];in[y]=cnt;e[cnt].f=0;
}
bool bfs()
{
    memset(dep,0,sizeof(dep));
    while(!que.empty())	que.pop();
    dep[s]=1;que.push(s);
    while(!que.empty())
    {
        //printf("QAQ");
        int x=que.front();que.pop();
        for(int i=in[x];i;i=e[i].lt)
        {
            int y=e[i].to;
            if(e[i].f&&!dep[y])
            {
                dep[y]=dep[x]+1;
                if(y==t)	return 1;
                que.push(y);
            }
        }
    }
    return dep[t]!=0;
}
int dfs(int x,int f)
{
    //printf("QAQ");
    if(x==t||!f)	return f;
    int cur=f;//printf("QAQ");
    for(int i=in[x];i;i=e[i].lt)
    {
        int y=e[i].to;
        if(dep[y]==dep[x]+1&&e[i].f)
        {
            int tmp=dfs(y,min(e[i].f,cur));
            //if(!tmp)	dep[y]=-1;
            e[i].f-=tmp;e[i^1].f+=tmp;cur-=tmp;
            if(!cur)	break;
        }
    }
    dep[x]=-1;
    return f-cur;
}
int c[300],r[300];
int dinic()
{
    int ans=0,w;
    while(bfs())
    {
        //while(w=dfs(s,inf))
        //{	
            ans+=dfs(s,inf);
            //printf("%d
",w);
        //}
    }
        
    //printf("%d ",ans);
    return ans;
}
int main()
{
    int n,m,i,j,tot=0;
    scanf("%d%d",&m,&n);
    s=n+m+1;t=n+m+2;//nn=n+m+2;
    for(i=1;i<=m;i++)
    {
        scanf("%d",&r[i]);
        add(s,i,r[i]);
        tot+=r[i];
    }
    for(i=1;i<=n;i++)
    {
        scanf("%d",&c[i]);
        add(i+m,t,c[i]);
        for(j=1;j<=m;j++)
            add(j,i+m,1);
    }
    if(dinic()==tot)
    {
        printf("1
");
        for(i=1;i<=m;i++)
        {
            for(int j=in[i];j;j=e[j].lt)
            {
                if(e[j].to==s)	continue;
                if(!e[j].f)	printf("%d ",e[j].to-m);
            }
            printf("
");
        }
    }
    else	printf("0
");
    return 0;
}
原文地址:https://www.cnblogs.com/hanyuweining/p/10321958.html