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 }
复制代码

 

posted @   *zzq  阅读(211)  评论(0编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· 赶AI大潮:在VSCode中使用DeepSeek及近百种模型的极简方法
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
历史上的今天:
2017-07-30 HDU 2795 线段树单点更新
2017-07-30 bzoj 1087 状压dp
点击右上角即可分享
微信分享提示