洛谷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。

 

出题人的节操呢?

 

二分答案+SPFA

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<queue>
 8 using namespace std;
 9 const int mxn=1e5+10;
10 int read(){
11     int x=0,f=1;char ch=getchar();
12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 struct edge{
17     int v,nxt;
18     int dis;
19 }e[mxn];
20 int hd[mxn],cnt=0;
21 void add_edge(int u,int v,int dis){
22     e[++cnt].nxt=hd[u];e[cnt].v=v;e[cnt].dis=dis;hd[u]=cnt;
23     return;
24 }
25 int n,m,s,t;
26 int dis[mxn];
27 bool inq[mxn];
28 queue<int>q;
29 bool SPFA(int s,int t,int limit){
30     memset(dis,0x3f,sizeof dis);
31     while(!q.empty()) q.pop();
32     int i,j;
33     dis[s]=0;
34     inq[s]=1;
35     q.push(s);
36     while(!q.empty()){
37         int u=q.front();
38         q.pop();
39         for(i=hd[u];i;i=e[i].nxt){
40             if(e[i].dis>limit)continue;
41             int v=e[i].v;
42             if(dis[v]>dis[u]+e[i].dis){
43                 dis[v]=dis[u]+e[i].dis;
44                 if(!inq[v]){
45                     inq[v]=1;
46                     q.push(v);
47                 }
48             }
49         }
50         inq[u]=0;
51     }
52     if(dis[t]<0x3f3f3f3f)return 1;
53     return 0;
54 }
55 int main(){
56     n=read();m=read();s=read();t=read();
57     int i,j;
58     int u,v,d;
59     for(i=1;i<=m;i++){
60         u=read();v=read();d=read();
61         add_edge(u,v,d);
62         add_edge(v,u,d);
63     }
64     int l=0,r=10000;
65     while(l<r){
66         int mid=(l+r)>>1;
67         if(SPFA(s,t,mid)){
68             r=mid;
69         }
70         else l=mid+1;
71 //        printf("test: %d\n",mid);
72     }
73     printf("%d\n",l);
74     return 0;
75 }

 

posted @ 2016-10-01 21:15  SilverNebula  阅读(218)  评论(0编辑  收藏  举报
AmazingCounters.com