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\n",maxflow()>=n?"YES":"NO"); } return 0; }