题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1491
游河
Time Limit: 1000 MS Memory Limit: 65535 K
Total Submit: 143(42 users) Total Accepted: 85(37 users) Rating: Special Judge: No
Description
假期,Hrbust集训队在Tang长老的带领下去河上坐船游玩。 但是很多队员想单独坐船游览风光,体验一个人的旅行。 但是教主说那样会很危险,而且似乎也没那么多的旅行路线。可是队员们还是坚持自己的想法,于是教主提了个要求:如果游览的路线足够一人一条,而且每条路线没有重复的水路的话,就同意大家的做法,不然,Tang长老就请大家集体吃冰棍,一起坐船去。
集训队这次一共去了 D 个人,(1<=D<=200),已知河道上一共N个河叉(2<=N<=200),大家都是从1号位置开始旅行的,终点为第 N 号位置,现在已知道在这N个位置之间有 M 条连通的水路(2<=M<=40000)。
请帮大家计算下存在的路线数是否够大家单人旅行的。
Input
Line 1: 河叉总数 N,道路总数 M,集训队人数 D。
Line 2…M+1:两个整数 A,B,表示位置 A 和 B 之间有一条直接连通的水路。
Output
Line1:如果存在的路径数够大家单人旅行(路径数>= D),输出“Orz!”,否则输出“Jiao Zhu v5!”。
Sample Input
2 2 1
1 2
1 2
7 9 5
1 2
2 3
3 7
1 4
4 3
4 5
5 7
1 6
6 7
Sample Output
Orz!
Jiao Zhu v5!
【题目分析】建图求最大流,然后与总人数相比较,然后看那个大就可以了。
【AC代码】
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INT_MAX 0x3fffffff
const int MAXN=210;
int map[MAXN][MAXN],n,p[MAXN];//map:邻接数组;n:点数;p:前驱数组;
bool EK_bfs(int start,int end)//广度优先算法寻找增光路
{
queue<int>que;//广度优先搜索队列
bool flag[MAXN];//标记数组
memset(flag,false,sizeof(flag));
memset(p,-1,sizeof(p));//初始化
que.push(start);
flag[start]=true;
while(!que.empty())
{
int e=que.front();
if(e==end)
{
return true;
}
que.pop();
for(int i=1;i<=n;i++)
{
if(map[e][i]&&!flag[i])
{
flag[i]=true;
p[i]=e;
que.push(i);
}
}
}
return false;
}
int EK_Max_Flow(int start,int end)
{
int u,flow_ans=0,mn;
while(EK_bfs(start,end))
{
mn=INT_MAX;
u=end;
while(p[u]!=-1)
{
mn=min(mn,map[p[u]][u]);
u=p[u];
}
flow_ans+=mn;
u=end;
while(p[u]!=-1)
{
map[p[u]][u]-=mn;
map[u][p[u]]+=mn;
u=p[u];
}
}
return flow_ans;
}
int main()
{
int m,k;
while(~scanf("%d%d%d",&n,&m,&k))
{
memset(map,0,sizeof(map));
int u,v;
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
map[u][v]+=1;
map[v][u]+=1;
}
int ans=EK_Max_Flow(1,n);
if(ans>=k)
{
printf("Orz!\n");
}
else
{
printf("Jiao Zhu v5!\n");
}
}
return 0;
}