判断最小生成树是否唯一
题目链接:https://vjudge.net/contest/67265#problem/B
具体思路:首先,跑一遍最小生成树,然后在求最小生成树的过程中,记录任意两个城市之间的最大边权,然后再暴力,枚举任意两个城市,然后如果这两个城市在最小生成树上有直接边相连,套用公式,(q[i].num+q[j].num)/(mst- road[i][j]),如果没有直接边相连,就套用公式(q[i].num+q[j].num)/(mst-maxx[i][j]),这里的maxx[i][j]指的是两个点之间的最大边权,然后输出最大结果就好了。(这题对精度限制还挺高的)。
AC代码:
#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
# define maxn 1000+100
# define eps 1e-6
double road[maxn][maxn];
int used[maxn][maxn];
int vis[maxn];
double maxx[maxn][maxn];
int father[maxn];
double dis[maxn];
int n;
double mst;
struct node
{
int x,y;
int num;
} q[maxn];
void init()
{
memset(vis,0,sizeof(vis));
memset(maxx,0,sizeof(maxx));
memset(used,0,sizeof(used));
memset(dis,inf,sizeof(dis));
}
void prim()
{
vis[1]=1;
for(int i=1; i<=n; i++)
{
dis[i]=road[1][i];
father[i]=1;
}
for(int i=1; i<n; i++)
{
double minn=inf;
int index=-1;
for(int j=1; j<=n; j++)
{
if(vis[j]==0&&minn>dis[j])
{
minn=dis[j];
index=j;
}
}
if(index==-1)break;
vis[index]=1;
mst+=minn;
used[father[index]][index]=used[index][father[index]]=1;//记录该边是否在最小生成树上。
for(int j=1; j<=n; j++)
{
if(vis[j]==0)
{
if(dis[j]>road[index][j])
{
father[j]=index;
dis[j]=road[index][j];
}
}
else if(vis[j]&&j!=index)
{
maxx[index][j]=maxx[j][index]=max(maxx[father[index]][j],dis[index]);
// j - > index 是 k - > father[index] 的一部分。
}
}
}
return ;
}
void judge()
{
double ans=-1.0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(i==j)continue;
if(used[i][j])
{
ans=max(ans,(q[i].num+q[j].num)*1.0/(mst-road[i][j]));
}
else
{
ans=max(ans,(q[i].num+q[j].num)*1.0/(mst-maxx[i][j]));
// cout<<i<<" "<<j<<" "<<maxx[i][j]<<endl;
}
}
}
printf("%.2lf\n",ans);
return ;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].num);
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
road[i][j]=road[j][i]=sqrt((q[i].x-q[j].x)*(q[i].x-q[j].x)*1.0+(q[i].y-q[j].y)*(q[i].y-q[j].y)*1.0);
}
}
mst=0.0;
prim();
judge();
}
return 0;
}