nyoj-310-河南省第四届省赛题目-二分+dinic

SECRET

时间限制:3000 ms  |  内存限制:65535 KB
难度:6
 
描述
Dr.Kong is constructing a new machine and wishes to keep it secret as long as possible. He has hidden in it deep within some forest and needs to be able to get to the machine without being detected. He must make a total of T (1 <= T <= 200) trips to the machine during its construction. He has a secret tunnel that he uses only for the return trips. The forest comprises N (2 <= N <= 200) landmarks (numbered 1..N) connected by P (1 <= P <= 40,000) bidirectional trails (numbered 1..P) and with a positive length that does not exceed 1,000,000. Multiple trails might join a pair of landmarks. To minimize his chances of detection, Dr.Kong knows he cannot use any trail on the forest more than once and that he should try to use the shortest trails. Help Dr.Kong get from the entrance (landmark 1) to the secret machine (landmark N) a total of T times. Find the minimum possible length of the longest single trail that he will have to use, subject to the constraint that he use no trail more than once. (Note well: The goal is to minimize the length of the longest trail, not the sum of the trail lengths.) It is guaranteed that Dr.Kong can make all T trips without reusing a trail.
 
输入
There are multi test cases.Your program should be terminated by EOF.
Line 1: Three space-separated integers: N, P, and T
Lines 2..P+1: Line i+1 contains three space-separated integers, A_i, B_i, and L_i,
indicating that a trail connects landmark A_i to landmark B_i with length L_i.
输出
Line 1: A single integer that is the minimum possible length of the longest segment of 
Dr.Kong 's route.
样例输入
7 9 2                                    
1 2 2
2 3 5
3 7 5
1 4 1
4 3 1
4 5 7
5 7 1
1 6 3
6 7 3
样例输出
5
来源
第四届河南省程序设计大赛
上传者
张云聪
    题目大意是给出一幅加权无向图,从起点走到终点走T次,每次都走最短路且每条路只能走一次,
问满足条件的方案中使得权值最小的那条边的权值达到最小,并输出。
  二分这个权值,然后将满足条件的边标记下。将所有能走的边的流量都置为1然后跑最大流,这样
最大流量就是能走的次数(从起点到终点)。
  
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 int N,P,T;
 5 struct Edge{
 6   int u,v,w;
 7 }e[40010];
 8 int g[220][220],vis[220],d[220];
 9 bool bfs(){
10   memset(vis,0,sizeof(vis));
11   vis[1]=1;
12   queue<int>q;
13   q.push(1);
14   d[1]=0;
15   while(!q.empty()){
16     int u=q.front();q.pop();
17     for(int i=1;i<=N;++i){
18       if(!vis[i]&&g[u][i]>0){
19         vis[i]=1;
20         d[i]=d[u]+1;
21         q.push(i);
22       }
23     }
24   }
25   return vis[N];
26 }
27 int dfs(int u,int a){
28   if(u==N || a==0) return a;
29   int flow=0,f;
30   for(int i=1;i<=N;++i){
31     if(g[u][i]&& d[i]==d[u]+1 && (f=dfs(i,min(a,g[u][i])))>0){
32       g[u][i]-=f;
33       g[i][u]+=f;
34       flow+=f;
35       a-=f;
36       if(!a) break;
37     }
38   }
39 return flow;
40 }
41 int solve(){
42   int res=0;
43   while(bfs()){
44     res+=dfs(1,inf);
45   }
46   return res;
47 }
48 bool ok(int mid){
49   memset(g,0,sizeof(g));
50   for(int i=1;i<=P;++i){
51     if(e[i].w<=mid){
52       g[e[i].u][e[i].v]++;
53       g[e[i].v][e[i].u]++;
54     }
55   }
56   return solve()>=T;
57 }
58 int main(){
59   while(scanf("%d%d%d",&N,&P,&T)!=EOF){
60     for(int i=1;i<=P;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
61     int l=0,r=1000010;
62     while(l<r){
63       int mid=l+((r-l)>>1);
64       if(ok(mid)) r=mid;
65       else l=mid+1;
66     }
67     cout<<l<<endl;
68   }
69   return 0;
70 }
原文地址:https://www.cnblogs.com/zzqc/p/9389521.html