uva1494 最小生成树--例题
这题说的是n个城市 建路 使他们联通然后 , 可以使用一条超级的路这条路不计入总长,此时路长度为B, 这条路链接的两个城市人口与和为A+B, 然后计算出最大的A/B
解题
先生成一颗最小生成树,然后 计算出这颗树上每两个节点之间要经过的最长的那条路,然后枚举每两个节点u 个v 求出答案
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 #include <cstdio> 5 #include <string.h> 6 #include <cmath> 7 using namespace std; 8 const int maxn =1000+5; 9 struct Edge{ 10 int u,v; 11 double dist; 12 bool operator <(const Edge &rhs)const{ 13 return dist<rhs.dist; 14 } 15 }; 16 vector<Edge>E; 17 struct point{ 18 int x,y; 19 }LOC[maxn]; 20 int P[maxn],fa[maxn]; 21 double maxcost[maxn][maxn]; 22 struct ed{ 23 int to; double dist; 24 }; 25 vector<ed>G[ maxn ]; 26 int fid(int u){ 27 return fa[u]==u? u :( fa[u] = fid( fa[u] ) ); 28 } 29 vector<int>use; 30 void dfs(int u, int per,double cost){ 31 for(int i =0; i < (int )use.size(); i++){ 32 int v = use[i]; 33 maxcost[u][v] = maxcost[v][u] = max( maxcost[per][v], cost); 34 } 35 use.push_back(u); 36 for(int i =0; i < (int)G[u].size() ; i++ ){ 37 ed e = G[u][i]; 38 if(e.to!=per) dfs(e.to,u,e.dist); 39 } 40 } 41 double distends(double x1, double y1, double x2, double y2){ 42 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 43 } 44 int main() 45 { 46 int cas; 47 scanf("%d",&cas); 48 for(int cc =1; cc <= cas; ++cc ){ 49 int n; 50 scanf("%d",&n); 51 for(int i=0; i<n; i++){ 52 scanf("%d%d%d",&LOC[i].x,&LOC[i].y,&P[i]); 53 G[i].clear(); fa[i] = i; 54 } 55 E.clear(); 56 for(int i=0; i < n; i++) 57 for(int j = i+1; j < n; j++ ){ 58 double d = distends(LOC[i].x,LOC[i].y, LOC[j].x, LOC[j].y); 59 E.push_back( (Edge){ i,j,d } ); 60 } 61 sort(E.begin() , E.end()); 62 double sum_dist=0; 63 int ge=n; 64 for(int i =0; i<(int)E.size(); i++ ){ 65 int u = E[i].u, v = E[i].v; 66 double dist = E[i].dist; 67 int fu = fid(u),fv =fid(v); 68 if(fu != fv){ 69 G[u].push_back( (ed){v,dist} ); G[v].push_back( (ed){u,dist} ); 70 fa[ fu ] = fv; 71 sum_dist+=dist; 72 ge--; if(ge==1) break; 73 } 74 } 75 memset(maxcost,0,sizeof(maxcost)); 76 use.clear(); 77 dfs(0,-1,0.0); 78 double ans =0; 79 for(int i =0; i<n; i++) 80 for(int j =i+1 ; j<n; j++ ){ 81 double c = 1.0*(P[i]+P[j])/(sum_dist-maxcost[i][j]); 82 if(ans<c){ 83 ans=c; 84 } 85 } 86 printf("%.2f\n",ans); 87 } 88 return 0; 89 }