码迷,mamicode.com
首页 > 其他好文 > 详细

sgu-242 Student's Morning

时间:2015-05-14 14:13:58      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:

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

解题思路:

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

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;
}

sgu-242 Student's Morning

标签:

原文地址:http://blog.csdn.net/qq_21995319/article/details/45719755

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!