TZOJ 3711 浪漫自习(最大流)

描述

如今的校园谈恋爱已是习以为常,这不,去上自习也要成双成对的。现在假设某班里有N对情侣从同一寝室楼出发,到达同一个教室上自习。途中,她们可能会经过长廊、静溪等一系列的景点观光游览。但情侣们不希望在途中碰到班里的其他情侣而扫了雅兴。现在给定包括寝室、教室、以及各个景点在内共有M个场景,以及这些场景之间的路径分布情况,请您帮忙为情侣们设计各自单独的散步路线。

输入

输入数据有多组,每组数据的第一行为2个正整数N(1<=N<=50)和M(2<=M<=50),分别表示共有N对情侣,M个场景,我们对场景从1~M进行编号。接下来的M行中,其中第i行的第一个数为正整数K,后面有K个正整数,表示与第i个场景之间有路径相连的场景编号。场景之间的路径是双向的,因此如果a与b之间有路径,那么b与a之间也必然有路径。我们始终假设:编号为1的场景是出发地——寝室楼,编号为2的场景是情侣们的目的地——自习教室。

当N和M均为0时输入结束。

输出

如果能够为情侣们设计出各自单独的散步路线(即除了出发地和目的地外,之间永远不会碰面),那么请输出YES,否则输出NO。

样例输入

3 5
3 3 4 5
3 3 4 5
2 1 2
2 1 2
2 1 2
4 5
3 3 4 5
3 3 4 5
2 1 2
2 1 2
2 1 2
0 0

样例输出

YES
NO

提示

样例的第一个实例对应的解决方案是:

1->3->2

1->4->2

1->5->2

题意

为N对情侣设置各自的路线(从1到2),要求路线不重叠,求是否能满足N对情侣

题解

每条边流量为1,源点S=1,汇点T=2,跑一遍最大流

代码

#include<bits/stdc++.h>
using namespace std;

const int N=205,M=205;
int c[N][N],pre[N],n,m;
bool bfs()
{
    int vis[N]={0};
    memset(pre,0,sizeof pre);
    queue<int>q;
    q.push(1);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int v=1;v<=m;v++)
        {
            if(c[u][v]>0&&!vis[v])
            {
                pre[v]=u;
                if(v==2)return true;
                vis[v]=1;
                q.push(v);
            }
        }
    }
    return false;
}
int maxflow()
{
    int flow=0;
    while(bfs())
    {
        int d=1e9;
        for(int i=2;i!=1;i=pre[i])d=min(d,c[pre[i]][i]);
        for(int i=2;i!=1;i=pre[i])
            c[pre[i]][i]-=d,
            c[i][pre[i]]+=d;
        flow+=d;
    }
    return flow;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF,n||m)
    {
        memset(c,0,sizeof c);
        for(int i=1,k;i<=m;i++)
        {
            scanf("%d",&k);
            for(int j=1,v;j<=k;j++)
            {
                scanf("%d",&v);
                c[i][v]=c[v][i]=1;
            }
        }
        printf("%s
",maxflow()>=n?"YES":"NO");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/taozi1115402474/p/9526824.html