TOJ 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。



提示

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

1->3->2

1->4->2

1->5->2

把联通的路径设为1,直接求最大流就可以了。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
using namespace std;
const int inf=0x7f7f7f7f;
int n,m,G[55][55],flow[55],pre[55];
queue<int> q;
int bfs(int s,int t)
{
	while(!q.empty())
	q.pop();
	memset(pre,-1,sizeof pre);
	pre[s]=0,flow[s]=inf;
	q.push(s);
	while(!q.empty())
	{
		int p=q.front();
		q.pop();
		if(p==t)break;
		for(int u=1;u<=n;u++)
		{
			if(u!=s&&G[p][u]>0&&pre[u]==-1)
			{
				pre[u]=p;
				flow[u]=min(flow[p],G[p][u]);
				q.push(u);
			}
		}
	}
	if(pre[t]==-1)return -1;
	return flow[t];
}
int EK(int s,int t)
{
	int delta=0,tot=0;
	while(1)
	{
		delta=bfs(s,t); 
		if(delta==-1)break;
		int p=t;
		while(p!=s)
		{
			G[pre[p]][p]-=delta;
			G[p][pre[p]]+=delta;
			p=pre[p];
		}
		tot+=delta;
	}
	return tot;
}
int main()
{
	int i,j,t,tl;
	while(scanf("%d%d",&m,&n))
	{
		if(n==0&&m==0)break;
		memset(G,0,sizeof G);		
		memset(flow,0,sizeof flow);		
		for(i=1;i<=n;i++)
		{
			scanf("%d",&t);
			for(j=0;j<t;j++)
			{
				scanf("%d",&tl);
				G[i][tl]=G[tl][i]=1;
			}
		}
		//printf("%d\n",EK(1,2));
		int sum=EK(1,2);
		if(sum>=m)
		printf("YES\n");
		else
		printf("NO\n");
	}
}



猜你喜欢

转载自blog.csdn.net/thewise_lzy/article/details/79902877
今日推荐