P1396 营救[最短路+二分]

题目描述

“咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……

妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了t区,而自己在s区。

该市有m条大道连接n个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从s至t的路线,使得经过道路的拥挤度最大值最小。

输入输出格式

输入格式:

第一行四个数字n,m,s,t。

接下来m行,每行三个数字,分别表示两个区和拥挤度。

(有可能两个区之间有多条大道相连。)

输出格式:

输出题目要求的拥挤度。

输入输出样例

输入样例#1:
3 3 1 3							
1 2 2
2 3 1
1 3 3
输出样例#1:
2

说明

数据范围

30% n<=10

60% n<=100

100% n<=10000,m<=2n,拥挤度<=10000

题目保证1<=s,t<=n且s<>t,保证可以从s区出发到t区。

样例解释:

小明的妈妈要从1号点去3号点,最优路线为1->2->3。

解析:

P1462这题几乎一毛一样,可以看我以前发的博客,比较详细。当然,之所以P1462是蓝题,主要是数据(可能吧)。

依旧是是用二分来约束最短路径上经过的的最大边权值,是一种比较巧妙的思路吧。

参考代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cstdlib>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #define N 20010
12 #define INF 23333333
13 using namespace std;
14 struct rec{
15     int next,ver,edge;
16 }g[N<<1];
17 int head[N],tot,n,m,s,t,d[N],f[N<<1];
18 bool v[N];
19 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
20 void add(int x,int y,int val)
21 {
22     g[++tot].ver=y,g[tot].edge=val;
23     g[tot].next=head[x],head[x]=tot;
24 }
25 bool dijkstra(int x,int k)
26 {
27     memset(v,0,sizeof(v));
28     memset(d,0x3f,sizeof(d));
29     d[x]=0;
30     q.push(make_pair(0,x));
31     while(q.size())
32     {
33         int index=q.top().second;q.pop();
34         if(v[index]) continue;
35         v[index]=1;
36         for(int i=head[index];i;i=g[i].next){
37             int y=g[i].ver,z=g[i].edge;
38             if(d[y]>d[index]+z&&f[k]>=z){
39                 d[y]=d[index]+z;
40                 q.push(make_pair(d[y],y));
41             }
42         }
43     }
44     if(d[t]>INF) return 0;
45     else return 1;
46 }
47 int main()
48 {
49     scanf("%d%d%d%d",&n,&m,&s,&t);
50     for(int i=1;i<=m;i++){
51         int x,y,val;
52         scanf("%d%d%d",&x,&y,&val);
53         f[i]=val;
54         add(x,y,val),add(y,x,val);
55     }
56     //¶þ·Ö 
57     sort(f+1,f+n+1);
58     int l=1,r=n,mid;
59     while(l<=r)
60     {
61         mid=(l+r)>>1;
62         if(dijkstra(s,mid)) r=mid-1;
63         else l=mid+1;
64     }
65     cout<<f[l]<<endl;
66     return 0;
67 }

啊咧?怎么乱码了?(逃

原文地址:https://www.cnblogs.com/DarkValkyrie/p/11030968.html