您的位置:首页 > 其它

HDU4081 Qin Shi Huang's National Road System【prim最小生成树+枚举】

2014-06-04 00:11 281 查看
先求出最小生成树,然后枚举树上的边,对于每条边“分别”找出这条割边形成的两个块中点权最大的两个
1.由于结果是A/B,A的变化会引起B的变化,两个制约,无法直接贪心出最大的A/B,故要通过枚举
2.不管magic road要加在哪里,加的边是否是最小生成树上的边,都会产生环,我们都要选择一条边删掉
注意删掉的边必须是树的环上的边,为了使结果最大,即找出最大的边
3.可以枚举两点,找出边,也可以枚举边,找出点,我是用后者,感觉比较容易写也好理解
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;
const int INF=(1<<31)-1;
int num;
bool visit[1111];
struct city{int x,y,popu;}point[1111];
vector<int>G[1111];
double getdis(city& a,city& b)
{
double dx=a.x-b.x;
double dy=a.y-b.y;
return sqrt(dx*dx+dy*dy);
}
double dis[1111][1111];
double prim()
{
double sum=0;
double dist[1111];
fill(dist,dist+1111,INF*1.0);
double minedge=INF;
int now=1,min_p;
int pre[1111];
memset(pre,0,sizeof(pre));
dist[now]=0;
visit[1]=true;
for(int t=1;t<num;t++)
{
for(int i=1;i<=num;i++)
{
if(i!=now && !visit[i] &&dist[i]>dis[now][i])
{
pre[i]=now;
dist[i]=dis[now][i];
}
}
minedge=INF;
for(int i=1;i<=num;i++)
{
if(!visit[i]&&minedge>dist[i])
{
minedge=dist[i];
min_p=i;
}
}
G[pre[min_p]].push_back(min_p);
G[min_p].push_back(pre[min_p]);
sum+=dis[min_p][pre[min_p]];
now=min_p;
visit[now]=true;
}
return sum;
}
int dfs(int v,int fa)
{
int maxn=point[v].popu;
for(int j=0;j<G[v].size();j++)
{
if(G[v][j]!=fa)
{
maxn=max(maxn,dfs(G[v][j],v));
}
}
return maxn;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("G:/1.txt","r",stdin);
freopen("G:/2.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&num);
for(int i=1;i<=num;i++)
{
scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].popu);
}
for(int i=1;i<=num;i++)
{
for(int j=1;j<=num;j++)
{
dis[i][j]=getdis(point[i],point[j]);
}
}
double sum=prim();
double ans=0;
for(int i=1;i<=num;i++)
{
for(int j=0;j<G[i].size();j++)
{
int t1=dfs(i,G[i][j]);
int t2=dfs(G[i][j],i);
ans=max(ans,(t1+t2)*1.0/(sum-dis[i][G[i][j]]));
}
}
//ans+=(1e-8);
printf("%.2f\n",ans);
for(int i=1;i<=num;i++)
{
G[i].clear();
}
memset(point,0,sizeof(city)*(num+1));
memset(visit,0,sizeof(bool)*(num+1));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: