汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边。1号点为教室,n号点为安全地带,每条边都只能容纳一定量的学生,超过楼就要倒塌,由于人数太多,校长决定让同学们分成几批逃生,只有第一批学生全部逃生完毕后,第二批学生才能从1号点出发逃生,现在请你帮校长算算,每批最多能运出多少个学生,x名学生分几批才能运完。
输入格式:
第一行3个整数n,m,x(x<2^31,n<=200,m<=2000);以下m行,每行三个整数a,b,c(a1,a<>b,0描述一条边,分别代表从a点到b点有一条边,且可容纳c名学生。
输出格式:
两个整数,分别表示每批最多能运出多少个学生,x名学生分几批才能运完。如果无法到达目的地(n号点)则输出“Orz Ni Jinan Saint Cow!”
输入样例#1:
6 7 7
1 2 1
1 4 2
2 3 1
4 5 1
4 3 1
3 6 2
5 6 1
输出样例#1:
3 3
【注释】
比如有图
1 2 100
2 3 1
100个学生先冲到2号点,然后1个1个慢慢沿2-3边走过去
18神牛规定这样是不可以的……
也就是说,每批学生必须同时从起点出发,并且同时到达终点
来一发Dinic。
这题比较少,我们想一下,如果要输送学生,我们只要找出每次可以通过的最大的学生数量就好。
然后用一点贪心的原理,每次都去用最大的输送方案输送学生(废话。。)
只要最大流不为0就一定能输送完成
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<queue>
6 #include<algorithm>
7 #define lli long long int
8 using namespace std;
9 const int MAXN=300001;
10 const int maxn=0x7fffff;
11 void read(int &n)
12 {
13 char c='+';int x=0;bool flag=0;
14 while(c<'0'||c>'9')
15 {c=getchar();if(c=='-')flag=1;}
16 while(c>='0'&&c<='9')
17 {x=(x<<1)+(x<<3)+c-48;c=getchar();}
18 flag==1?n=-x:n=x;
19 }
20 struct node
21 {
22 int u,v,flow,cap,nxt;
23 }edge[MAXN];
24 int head[MAXN];
25 int num=0;
26 int n,m,S,T,x;
27 int dis[MAXN];
28 int vis[MAXN];
29 int cur[MAXN];
30 void add_edge(int x,int y,int z)
31 {
32 edge[num].u=x;
33 edge[num].v=y;
34 edge[num].cap=z;
35 edge[num].flow=0;
36 edge[num].nxt=head[x];
37 head[x]=num++;
38 }
39 bool bfs(int bg,int ed)
40 {
41 memset(dis,-1,sizeof(dis));
42 queue<int>q;
43 q.push(bg);
44 dis[bg]=0;
45 while(!q.empty())
46 {
47 int p=q.front();
48 q.pop();
49 for(int i=head[p];i!=-1;i=edge[i].nxt)
50 {
51 if(dis[edge[i].v]==-1&&edge[i].cap>edge[i].flow)
52 {
53 vis[edge[i].v]=1;
54 dis[edge[i].v]=dis[edge[i].u]+1;
55 q.push(edge[i].v);
56 }
57 }
58 }
59 if(dis[ed]==-1)
60 return 0;
61 else return 1;
62 }
63 int dfs(int now,int a)// a:所有弧的最小残量
64 {
65 if(now==T||a<=0)
66 return a;
67
68 int flow=0,f;
69 for(int i=head[now];i!=-1;i=edge[i].nxt)
70 {
71 if(dis[now]+1==dis[edge[i].v]&&edge[i].cap-edge[i].flow>0)
72 {
73 f=dfs(edge[i].v,min(a,edge[i].cap-edge[i].flow));
74 edge[i].flow+=f;
75 edge[i^1].flow-=f;
76 flow+=f;
77 a-=f;
78 if(a<=0)break;
79 }
80 }
81 return flow;
82 }
83 void Dinic(int S,int T)
84 {
85 int ansflow=0;
86 int cs=0;
87 int maxflow=0;
88 for(int i=1;i<=n;i++)
89 cur[i]=head[i];
90 while(bfs(S,T))
91 {
92 int p=dfs(S,maxn);
93 cs++;
94 ansflow+=p;
95 maxflow=max(maxflow,p);
96 }// 求出层级
97 if(ansflow==0)
98 printf("Orz Ni Jinan Saint Cow!");
99 else
100 printf("%d %d",ansflow,(x%ansflow)==0?(x/ansflow):(x/ansflow+1));
101
102 //printf("%d",ansflow);
103
104 }
105 int main()
106 {
107 scanf("%d%d%d",&n,&m,&x);
108 //read(n);read(m);read(x);
109 // swap(n,m);
110 S=1;T=n;
111 // read(S);read(T);
112 for(int i=1;i<=n;i++)
113 head[i]=-1;
114 for(int i=1;i<=m;i++)
115 {
116 int x,y,z;
117 //read(x);read(y);read(z);
118 scanf("%d%d%d",&x,&y,&z);
119 add_edge(x,y,z);
120 add_edge(y,x,0);
121 }
122 Dinic(S,T);
123 return 0;
124 }