sgu-242 Student's Morning

来源:互联网 发布:手写笔 软件 编辑:程序博客网 时间:2024/05/16 02:17

题目大意:

N个人,K个大学,每个人有Gi个心仪的学校,为集合Si,然后然后这N个人可以去任意一个且仅一个他心仪的学校,问是否可以使得K个学校每个学校都有不小于2个人去。如果没有,输出”NO”,否则输出”YES”,然后接下来K行,每行一个数,表示去第i个学校的人有几个,接下来输出那几个人去哪个学校。PS:有的人可以不去学校,只要满足每个学校有2个及以上的人去就行了,不要求N个人每个人都去上学,比如可以在家浪。。。。。。

解题思路:

首先这道题目显然可以用有上下确界的可行流做,但是太麻烦了,直接跑最大流就行了啊。
首先原点St向所有的学生连一条流量为1的边,所有的学生向他心仪的学校连一条流量为1的边,然后每个学校向汇点En连一条流量为2的边,然后跑最大流,如果最后MaxFlow=K2说明是可行的,否则是不行的。

AC代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#define Min(a,b) ((a)>(b)?(b):(a))using namespace std;int G[510][510]={{0}};int f[510][510]={{0}};int N,K;int st=0,en;int dist[510]={0};int dui[510]={0};int duip=0;void bfs(){    duip=0;    dui[++duip]=en;    for(int i=1;i<=duip;i++)    {        int u=dui[i];        for(int v=0;v<=en;v++)        {            if(G[v][u]-f[v][u]>0 && dist[v]>dist[u]+1)            {                dist[v]=dist[u]+1;                dui[++duip]=v;            }        }    }    return;}int Max_Flow(int now,int Max){    if(now==en) return Max;    int sum=0;    for(int i=0;i<=en;i++)    {        if(G[now][i]-f[now][i]>0 && dist[now]==dist[i]+1)        {            int tmp=Min(G[now][i]-f[now][i],Max);            tmp=Max_Flow(i,tmp);            sum+=tmp;            Max-=tmp;            f[now][i]+=tmp;            f[i][now]-=tmp;            if(Max==0) return sum;        }    }    return sum;}void prt(){    for(int i=N+1;i<=en-1;i++)    {        printf("2 ");        for(int j=1;j<=N;j++)            if(f[j][i]==1)                printf("%d ",j);        puts("");    }    return;}int main(){    scanf("%d%d",&N,&K);    en=N+K+1;    for(int i=1;i<=N;i++)    {        int num=0;        scanf("%d",&num);        for(int j=1;j<=num;j++)        {            int sb;            scanf("%d",&sb);            G[i][sb+N]=1;        }        G[st][i]=1;    }    for(int i=1;i<=K;i++)        G[i+N][en]=2;    int ans=0;    for(;;)    {        memset(dist,0x3f3f3f3f,sizeof(dist));        dist[en]=0;        bfs();        if(dist[st]==0x3f3f3f3f)            break;        ans+=Max_Flow(st,2e9);        if(ans==K*2) break;    }    if(ans!=K*2)        cout<<"NO"<<endl;    else    {        cout<<"YES"<<endl;        prt();    }    return 0;}
0 0
原创粉丝点击