hdu 4081Qin Shi Huang's National Road System(最小生成树变形)

来源:互联网 发布:贝克汉姆球衣淘宝 编辑:程序博客网 时间:2024/04/29 02:07

 

 

http://acm.hdu.edu.cn/showproblem.php?pid=4081

 

 

题目大意:

            秦始皇要修建最小费用的道路,有个道士可以建一条免费魔法道路,但是道士要求这条道路连接的两个城市的人口要最多,秦始皇不同意,权衡之下决定用A/B的最大比值来修建魔法道路。

           A:魔法道路连接的城市总人口

           B:除魔法道路外需要修建的道路总长

           先生成一棵最小生成树,枚举每条边(在A一定的情况下,B越小,A/B越大),若这条边在树上,减去这条边的权值,否则减去成环最大边的权值。

 

 

 

#include<iostream>#include<cstring>#include<queue>#include<cmath>#include<cstdio>using namespace std;#define N 1001double INF=99999999.0;double map[N][N],low[N],max1[N][N];int p[N],path[N][N];void prim(int n){int i,j,vis[N],pos,now[N];double min,sum=0,max=0;for(i=0;i<n;i++){low[i]=map[0][i];vis[i]=0;now[i]=0;}vis[0]=1;memset(max1,0,sizeof(max1));memset(path,0,sizeof(path));for(i=0;i<n;i++){min=INF;pos=-1;for(j=0;j<n;j++)if(!vis[j]&&low[j]<min){min=low[j];pos=j;}if(pos==-1)break;vis[pos]=1;path[now[pos]][pos]=path[pos][now[pos]]=1;//保存在树上的边,pos连接的边用now[]来保存sum+=min;for(j=0;j<n;j++)//次小生成树的枚举if(vis[j]&&j!=pos)max1[pos][j]=max1[j][pos]=max1[j][now[pos]]>low[pos]?max1[j][now[pos]]:low[pos];for(j=0;j<n;j++)if(low[j]>map[pos][j]){low[j]=map[pos][j];now[j]=pos;}}for(i=0;i<n;i++)for(j=0;j<n;j++){if(i!=j){if(path[i][j]==1){if((p[i]+p[j])/(sum-map[i][j])>max)max=(p[i]+p[j])/(sum-map[i][j]);}else{if((p[i]+p[j])/(sum-max1[i][j])>max)max=(p[i]+p[j])/(sum-max1[i][j]);}}}printf("%.2lf\n",max);}int main(){int t,n,i,x[N],y[N],j;cin>>t;while(t--){cin>>n;for(i=0;i<n;i++)cin>>x[i]>>y[i]>>p[i];for(i=0;i<n;i++)for(j=0;j<n;j++){if(i==j)map[i][j]=INF;elsemap[i][j]=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}prim(n);}return 0;}


 

0 0