poj2253--Frogger--最小瓶颈树
Description
给出两只青蛙的坐标A、B,和其他的n-2个坐标,任一两个坐标点间都是双向连通的。显然从A到B存在至少一条的通路,每一条通路的元素都是这条通路中前后两个点的距离,这些距离中又有一个最大距离。
现在要求求出所有通路的最大距离,并把这些最大距离作比较,把最小的一个最大距离作为青蛙的最小跳远距离。
Sample Input
2 0 0 3 4 3 17 4 19 4 18 5 0
Sample Output
Scenario #1 Frog Distance = 5.000 Scenario #2 Frog Distance = 1.414
题解:
本题可以用二分或者kruskal来做。若是二分,抓住题中“最大边权最小”的要求,由此最优转化为判定可行解。
也可以看作是最短路的变形应用,这里贴一发kruskal的水解法。
首先考虑我们是如何转化到最小生成树问题的,题中的意思可以看作加若干条边,使得1和2联通。
其次回想一下kruskal求最小生成树的过程,第一步是将边从小到大排序,再贪心加边。放到本题中,相当于依次从小到大加边,直到1和2联通为止。
显然因为kruskal在加边时已经是从小到大的了,那么答案显然是最后加的那条边。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cmath> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 const int maxn=1009; 8 const int maxm=40009; 9 10 int fa[maxm],tot,n;//tot记录边数 11 double x[maxn],y[maxn],ans; 12 13 struct edge 14 { 15 int frm,to; 16 double w; 17 }e[maxm]; 18 19 bool cmp(edge a,edge b) 20 { 21 return a.w<b.w; 22 } 23 24 double getlen(int a,int b) 25 { 26 return sqrt( (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]) ); 27 } 28 void init() 29 { 30 tot=0; 31 for(int i=0;i<=maxn;i++) 32 { 33 fa[i]=i; 34 } 35 } 36 37 int find(int x) 38 { 39 if(x!=fa[x]) 40 fa[x]=find(fa[x]); 41 return fa[x]; 42 } 43 44 bool same_set(int x,int y) 45 { 46 return find(x)==find(y); 47 } 48 49 void uni(int x,int y) 50 { 51 int u=find(x),v=find(y); 52 if(u==v)return; 53 fa[u]=v; 54 } 55 56 void kruskal() 57 { 58 ans=0.0; 59 sort(e+1,e+tot+1,cmp); 60 for(int i=1;i<=tot;i++) 61 { 62 if(find(1)==find(2))break; 63 if(!same_set(e[i].frm,e[i].to)) 64 { 65 uni(e[i].frm,e[i].to); 66 ans=e[i].w; 67 } 68 } 69 } 70 71 int main() 72 { 73 int cas=0; 74 while(scanf("%d",&n)!=EOF) 75 { 76 if(n==0)break; 77 for(int i=1;i<=n;i++) 78 { 79 scanf("%lf%lf",&x[i],&y[i]); 80 } 81 init(); 82 for(int i=1;i<=n;i++) 83 { 84 for(int j=1;j<=n;j++) 85 { 86 if(i==j)continue; 87 e[++tot].frm=i; 88 e[tot].to=j; 89 e[tot].w=getlen(i,j); 90 } 91 } 92 kruskal(); 93 printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cas,ans); 94 } 95 return 0; 96 } 97 /* 98 8 99 0 0 100 2 4 101 0 2 102 1 0 103 2 0 104 2 1 105 2 2 106 2 3 107 108 109 110 ans=1.000 111 */