【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
【题意】
有n个绿洲, m条道路,每条路上有一个温度,和一个路程长度,从绿洲s到绿洲t,求一条道路的最高温度尽量小, 如果有多条, 选一条总路程最短的。
Input
Input consists of several test cases. Your program must process all of them.
The first line contains two integers N and E (1 ≤ N ≤ 100; 1 ≤ E ≤ 10000) where N represents the
number of oasis and E represents the number of paths between them. Next line contains two distinct
integers S and T (1 ≤ S, T ≤ N) representing the starting point and the destination respectively. The
following E lines are the information the group gathered. Each line contains 2 integers X, Y and 2 real
numbers R and D (1 ≤ X, Y ≤ N; 20 ≤ R ≤ 50; 0 < D ≤ 40). It means there is a path between X and
Y , with length D km and highest temperature RoC. Each real number has exactly one digit after the
decimal point. There might be more than one path between a pair of oases.
Output
Print two lines for each test case. The first line should give the route you find, and the second should
contain its length and maximum temperature.
Sample Input
6 9
1 6
1 2 37.1 10.2
2 3 40.5 20.7
3 4 42.8 19.0
3 1 38.3 15.8
4 5 39.7 11.1
6 3 36.0 22.5
5 6 43.9 10.2
2 6 44.2 15.2
4 6 34.2 17.4
Sample Output
1 3 6
38.3 38.3
【分析】
我们可以先求出最大温度的最小值,然后把小于等于这个温度的边加进图中跑最短路。
最短路就不说了,现在就是要求最小瓶颈路。
最小瓶颈路有两个方法,
1、二分+BFS
二分之后沿着小于等于这个温度的边走,只需判断能否走到终点,所以是mlogn的。
2、
但其实可以nlogn把图上所有两点的最小瓶颈路求出来,就是求出最小瓶颈树,那么两点之间的唯一路径就是他们的最小瓶颈路。
而最小生成树就是一个最小瓶颈树。
[其实这个,我也不是很会证明的说- -谁能告诉我- -]
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define Maxn 110 10 #define Maxm 10010 11 #define INF 0xfffffff 12 13 int n,m,st,ed; 14 15 struct node 16 { 17 int x,y,c,d; 18 int next; 19 }tt[Maxm],t[Maxm*2]; 20 int len,first[Maxn]; 21 22 bool cmp(node x,node y) {return x.c<y.c;} 23 // double mymax(double x,double y) {return x>y?x:y;} 24 int mymax(int x,int y) {return x>y?x:y;} 25 26 int fa[Maxn]; 27 int ffa(int x) 28 { 29 if(fa[x]!=x) fa[x]=ffa(fa[x]); 30 return fa[x]; 31 } 32 33 void ins(int x,int y,int c) 34 { 35 t[++len].x=x;t[len].y=y;t[len].c=c; 36 t[len].next=first[x];first[x]=len; 37 } 38 39 int mx[Maxn]; 40 void dfs(int x,int f) 41 { 42 for(int i=first[x];i;i=t[i].next) if(t[i].y!=f) 43 { 44 int y=t[i].y; 45 mx[y]=mymax(mx[x],t[i].c); 46 dfs(y,x); 47 } 48 } 49 50 queue<int > q; 51 int pre[Maxn],dis[Maxn]; 52 bool inq[Maxn]; 53 void spfa() 54 { 55 while(!q.empty()) q.pop(); 56 // for(int i=1;i<=n;i++) dis[i]=INF; 57 memset(dis,63,sizeof(dis)); 58 memset(inq,0,sizeof(inq)); 59 q.push(ed);inq[ed]=1;dis[ed]=0; 60 while(!q.empty()) 61 { 62 int x=q.front(); 63 for(int i=first[x];i;i=t[i].next) 64 { 65 int y=t[i].y; 66 if(dis[y]>dis[x]+t[i].c) 67 { 68 dis[y]=dis[x]+t[i].c; 69 pre[y]=x; 70 if(!inq[y]) 71 { 72 q.push(y); 73 inq[y]=1; 74 } 75 } 76 } 77 inq[x]=0;q.pop(); 78 } 79 if(dis[st]>=INF-10000) return; 80 int now=st; 81 while(now!=ed) 82 { 83 printf("%d ",now); 84 now=pre[now]; 85 } 86 printf("%d\n",ed); 87 printf("%.1lf %.1lf\n",dis[st]*1.0/10,mx[st]*1.0/10); 88 } 89 90 int main() 91 { 92 while(scanf("%d%d",&n,&m)!=EOF) 93 { 94 scanf("%d%d",&st,&ed); 95 for(int i=1;i<=m;i++) 96 { 97 double c,d; 98 scanf("%d%d%lf%lf",&tt[i].x,&tt[i].y,&c,&d); 99 tt[i].c=(int)round(c*10);tt[i].d=(int)round(d*10); 100 } 101 sort(tt+1,tt+1+m,cmp); 102 for(int i=1;i<=n;i++) fa[i]=i; 103 int cnt=0; 104 memset(first,0,sizeof(first)); 105 len=0; 106 for(int i=1;i<=m;i++) 107 { 108 if(ffa(tt[i].x)!=ffa(tt[i].y)) 109 { 110 fa[ffa(tt[i].x)]=ffa(tt[i].y); 111 cnt++; 112 ins(tt[i].x,tt[i].y,tt[i].c); 113 ins(tt[i].y,tt[i].x,tt[i].c); 114 } 115 if(cnt==n-1) break; 116 } 117 mx[ed]=0; 118 dfs(ed,0); 119 len=0; 120 memset(first,0,sizeof(first)); 121 for(int i=1;i<=m;i++) if(tt[i].c<=mx[st]) 122 { 123 ins(tt[i].x,tt[i].y,tt[i].d); 124 ins(tt[i].y,tt[i].x,tt[i].d); 125 } 126 spfa(); 127 } 128 return 0; 129 }
2016-11-01 15:57:34