标签:建图 iostream 代码 style memset vector long print san
题意:
秦始皇要修路,n个城市,给出x,y坐标,和人口。
城市与城市之间的距离为它们的欧几里德距离。
徐福会魔法,他可以不费任何钱在两个城市中变出一条路出来。
问:
怎样才能使徐福变的那个路两边的城市人口之和最大,让秦始皇修的剩下的路花费的值最小,输出它们的比。
方法:
建图,求最小生成树,然后枚举每对城市u,v,始皇帝花的剩下的路的钱最小就是最小生成树的值减去最小生成树上的u,v之间路径上的最大权值。
然后比较枚举的每个边的情况的优劣即可。
代码:
#include<iostream>
using namespace std;
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<queue>
#include<algorithm>
#include<vector>
int n,m;
typedef long long LL;
struct point{
LL x,y;
};
double countdist(const point&x,const point &y){
double ans1=0,ans2=0,ans=0;
ans1=x.x-y.x;
ans2=x.y-y.y;
if (ans1<0) ans1*=-1;if (ans2<0) ans2*=-1;
ans=sqrt((double)(ans1*ans1)+(double)(ans2*ans2));
return ans;
}
point a[3000];
struct bian{
int l;int r;double d;
bool operator<(const bian& pt)const{
return this->d<pt.d;
}
};
struct todata{
int point;double d;
};
struct bcj{
int fa[3000];
void init(){
for (int i=0;i<3000;i++) fa[i]=i;
}
int getfa(int x){
if (fa[x]==x) return x;
else{
int root=getfa(fa[x]);
fa[x]=root;
return root;
}
}
void connect(int x,int y){
int fx=getfa(x),fy=getfa(y);
fa[fx]=fy;
getfa(fx);
}
int judge(int x,int y){
int fx=getfa(x),fy=getfa(y);
if (fx==fy) return 1;
else return 0;
}
};
bian maps[1100000];
LL people[1100];
int b;
int mapsnum=0;
bcj jh;
vector<todata> tu[1100];
double maxvalue[1100][1100];
int v[1100];
int dq;
void dfs(int x,double dqmax){
maxvalue[dq][x]=dqmax;
// cout<<dq<<" "<<x<<" "<<dqmax<<endl;
v[x]=1;
for (int i=0;i<tu[x].size();i++){
int nb=tu[x][i].point;
if (v[nb]) continue;
double ndq=dqmax;
if (tu[x][i].d>dqmax) ndq=tu[x][i].d;
dfs(nb,ndq);
}
}
void getmaxvalue(){
for (int i=1;i<=n;i++){
memset(v,0,sizeof(v));
dq=i;
dfs(i,0);
}
}
void deal(){
scanf("%d",&n);
mapsnum=0;
for (int i=0;i<=n;i++) tu[i].clear();
for (int i=1;i<=n;i++){
int dx,dy;
scanf("%d%d",&dx,&dy);
a[i].x=dx;a[i].y=dy;
scanf("%lld",&people[i]);
}
for (int i=2;i<=n;i++){
for (int j=1;j<i;j++){
maps[mapsnum].l=j;maps[mapsnum].r=i;
maps[mapsnum++].d=countdist(a[i],a[j]);
}
}
sort(maps,maps+mapsnum);
int js;
int k=0;
int ljnum=0;
double scsans=0;
jh.init();
while(k<mapsnum){
int l,r;l=maps[k].l,r=maps[k].r;
//cout<<l<<" "<<r<<" "<<jh.getfa(l)<<" "<<jh.getfa(r)<<" "<<jh.judge(l,r)<<endl;
if (!jh.judge(l,r)){
jh.connect(l,r);
ljnum++;
scsans+=maps[k].d;
//cout<<k<<" "<<"边权:"<<maps[k].d<<" "<<"当前ans: "<<scsans<<endl;
todata pt;
pt.d=maps[k].d;pt.point=r;
tu[l].push_back(pt);
pt.point=l;
tu[r].push_back(pt);
}
if (ljnum>=n-1) break;
k++;
}
// cout<<"maxscs: "<<scsans<<"\t"<<"maxk: "<<k<<"\tmaxnum: "<<mapsnum<<endl;
getmaxvalue();
double ans=0;
for (int i=mapsnum-1;i>=0;i--){
LL rq=people[maps[i].l]+people[maps[i].r];
double dd=maxvalue[maps[i].l][maps[i].r];
double zans;
double nd=scsans-dd;
zans=(double)rq/nd;
//cout<<people[maps[i].l]<<" "<<people[maps[i].r]<<endl;
//cout<<"zans "<<zans<<"\t"<<"ans "<<ans<<"rq: "<<rq<<" l: "<<maps[i].l<<" r:"<<maps[i].r<<endl;
if (zans>ans) ans=zans;
}
printf("%.2f\n",ans);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
deal();
}
return 0;
}
UVALive - 5713 Qin Shi Huang's National Road System
标签:建图 iostream 代码 style memset vector long print san
原文地址:http://www.cnblogs.com/xfww/p/7628035.html