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 }
啊咧?怎么乱码了?(逃