网络流24题 圆桌聚餐

来源:互联网 发布:java如何utf8转换为gbk 编辑:程序博客网 时间:2024/06/06 00:58

原题位置: http://cogs.sxysxy.org:8080/cogs/problem/problem.php?pid=729

(这个有SPJ)

这个题是一个裸的网络流板子题,都说网络流难在建图,我只能说+1;

这个题的建图方式有两种,但大同小异;

<1> 超级源,超级汇,拆点,拆出的两个点之间为代表数(桌子数),代表和桌子之间的边是1,超级源(汇)与代表(桌子)之间是正无穷;
<2> 超级源,超级汇,超级源(汇)与代表(桌子)之间是代表数(桌子数),代表与桌子之间是1;

(我用的是<1>)

然后跑最大流了,如果最大流等于代表数的话,即所有代表都可以合法的找到桌子,即输出1,否则输出0;

这题描述不清,输出0的话就可以exit(0)了;

至于这道题的一个点就是输出路径(??!路径??!);

就看如果代表和桌子之间的正向边没流量的话,证明该代表选了这张桌子,然后输出就好了;

要是WA了,就开大点数组,然后找个有SPJ的网站,如果还没A,就自行debug吧;

—————————————123——————————————-

#include<iostream>#include<stdio.h>#include<algorithm>#include<vector>#include<queue>#define II int#define B bool#define R register#define I 1000using namespace std;struct node {    II from,to;    II flow;};vector <node> Q;vector <II> aa[I*I];II dis[I], bit[I], kl[I][I], peo[I], tab[I];II n,m,ans,en,_tot;void add(R II x,R II y,R II z){    Q.push_back((node) {x,y,z});    aa[x].push_back(Q.size()-1);    Q.push_back((node) {y,x,0});    aa[y].push_back(Q.size()-1);}B bfs(){    queue <II> op;    op.push(0);    dis[0]=1;    while (!op.empty()) {        II o=op.front(); op.pop();        for(R II i=0;i<aa[o].size();i++)        {            R node now=Q[aa[o][i]];            R II go=now.to;            if(!dis[go]&&now.flow) {                dis[go]=dis[o]+1;                op.push(go);            }        }    }    return dis[en];}II dfs(R II x,R II a){    R II f=0,now_flow=0;    if(!a||x==en) return a;    for(R II& i=bit[x];i<aa[x].size();i++)    {        R node& now=Q[aa[x][i]];        R II go=now.to;        if(dis[go]==dis[x]+1&&(f=dfs(go,min(a,now.flow)))>0) {            now_flow+=f;            Q[aa[x][i]].flow-=f;            a-=f;            Q[aa[x][i]^1].flow+=f;            if(!a) return now_flow;        }    }    return now_flow;}int main(){    freopen("roundtable.in","r",stdin);    freopen("roundtable.out","w",stdout);//  freopen("1.in","r",stdin);    scanf("%d%d",&n,&m);    for(R II i=1;i<=n;i++) scanf("%d",&peo[i]), _tot+=peo[i];    for(R II i=1;i<=m;i++) scanf("%d",&tab[i]);    en=n+n+m+m+1;    for(R II i=1;i<=n;i++) add(0,i,123456789);    for(R II i=n+n+m+1;i<=n+n+m+m;i++) add(i,en,123456789);    for(R II i=1;i<=n;i++) add(i,n+i,peo[i]);    for(R II i=n+n+1;i<=n+n+m;i++) add(i,m+i,tab[i-n-n]);    for(R II i=n+1;i<=n+n;i++)    {        for(R II j=n+n+1;j<=n+n+m;j++)           add(i,j,1);    }    while (bfs()) {        for(R II i=0;i<=en;i++) bit[i]=0;        ans+=dfs(0,123456789);        for(R II i=0;i<=en;i++) dis[i]=0;    }    ans==_tot? printf("1\n"): printf("0\n");    if(ans==_tot) {        for(R II i=n+1;i<=n+n;i++)        {            for(R II j=0;j<aa[i].size();j++)            {                if(!Q[aa[i][j]].flow) printf("%d ",Q[aa[i][j]].to-n-n);                // 找路径,如果该正向边没流量的话,输出;            }            printf("\n");        }    }    exit(0);} 

————————————–456———————————————

by pretend-fal

END;

原创粉丝点击