部分代码没有用,只是为了测试 vector都没有用到
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <set>
#define DEBUG 1
#define MAXN 1005
#define MAXM 1000005
using namespace std;
int T,N;
struct V{
int num;
int x;
int y;
int P;
V(){}
V(int x,int y,int p,int num):
x(x),y(y),P(p),num(num){}
bool operator ==(V &v){
if(this->x == v.x&& this->y == v.y)
return true;
return false;
}
};
struct EDGE{
int from;
double w;
int to;
EDGE(){}
EDGE(int from,int to,int w):
from(from),to(to),w(w){
//this->value = (from.P+to.P)/w;
}
bool operator< (const EDGE &a){
if(this->w <a.w){
return true;
}else{
return false;
}
}
//
// bool operator<(const EDGE &a,const EDGE &b){
//
// if(a.w <b.w){
// return true;
// }else{
// return false;
// }
// }
};
struct NODE{
int num;
int next;
};
//链表结构
NODE HEAD[MAXN];
//边的集合
vector<EDGE> VEC_EDGES;
//最小生成树的集合
vector<EDGE> VEC_MST;
//所有点的集合
vector<V> VEC_VS;
EDGE EDGES[MAXM];
int M;
//最小生成树
int MST[MAXN][MAXN] = {0};
//最大路径权重
double MAX_W = 0;
//寻找路径的时候用
bool VIS[MAXN] = {false};
//寻找到的路径
vector<int> VEC_PATH;
//所有边的权重
double MAP[MAXN][MAXN] = {0};
double MAX_LENGTH[MAXN][MAXN] = {0};
//并查集
int SET[MAXN] = {0};
int find_x(int x){
if(SET[x] ==0){
return x;
}else{
return SET[x] = find_x(SET[x]);
}
}
void union_set(int x,int y){
if(find_x(x) == find_x(y))
return;
SET[y] = find_x(x);
}
double dis(int x1,int y1,int x2,int y2){
return sqrt((y2-y1)*(y2-y1) + (x2-x1)*(x2-x1));
}
//建立边
void build_edge(){
M=0;
for(int i=1;i<=N;i++){
V &from = VEC_VS[i-1];
for(int j =i+1;j<=N;j++){
V &to = VEC_VS[j-1];
if(j!=i){
EDGE edge;
edge.from = from.num;
edge.to = to.num;
edge.w = dis(from.x,from.y,to.x,to.y);
EDGES[M++] = edge;
MAP[from.num][to.num] = MAP[to.num][from.num] = edge.w;
}
}
}
}
//链表方式实现
void find_max_len(){
}
//krusal
void mst(){
//首先排序
sort(EDGES,EDGES+M);
memset(SET,0,sizeof(SET));
//建立集合
//build_vs();
for(int i=0;i<M;i++){
EDGE &edge = EDGES[i];
int x = find_x(edge.from);
int y = find_x(edge.to);
if(x != y){
vector<int> vec_x;
vector<int> vec_y;
for(int i=1;i<=N;i++){
if(x== find_x(i))
vec_x.push_back(i);
if(y==find_x(i))
vec_y.push_back(i);
}
for(int i =0;i<vec_x.size();i++){
for(int j = 0;j<vec_y.size();j++){
int xx = vec_x[i], yy = vec_y[j];
MAX_LENGTH[xx][yy] = MAX_LENGTH[yy][xx] = edge.w;
}
}
union_set(x,y);
//set_MST.insert(edge);
VEC_MST.push_back(edge);
//如果找到一个边
//PRE[edge.to.num] = edge.from.num;
MST[edge.from][edge.to] = 1;
MST[edge.to][edge.from] = 1;
}
}
}
//寻找路径
bool find_path(int beginn,int endd){
VIS[beginn] = true;
if(beginn == endd)
return true;
for(int i=1;i<=N;i++){
if(MST[beginn][i]&& !VIS[i]){
//如果找到结果,则返回
if(find_path(i,endd)){
VEC_PATH.push_back(i);
return true;
}
}
}
return false;
}
double find_max(){
double max_w =0;
double t=0;
for(int i=0;i<VEC_PATH.size()-1;i++){
t = MAP[VEC_PATH[i]][VEC_PATH[i+1]];
if(t>max_w)
max_w = t;
}
return max_w;
}
void find_max_length(int beginn,int cur,double maxn){
VIS[cur] = true;
for(int i=1;i<=N;i++){
if(MST[cur][i] && !VIS[i]){
double t;
if(MAP[cur][i] > maxn){
MAX_LENGTH[beginn][i] = MAX_LENGTH[i][beginn] = MAP[cur][i];
t= MAP[cur][i];
}
else{
MAX_LENGTH[beginn][i] = MAX_LENGTH[i][beginn] = maxn;
t= maxn;
}
find_max_length(beginn,i,t);
}
}
}
double solve(){
double sum_dis = 0;
for(int i=0;i<VEC_MST.size();i++){
sum_dis += VEC_MST[i].w;
}
double best = 0,t_dis,value;
//每次从中拿出一条边进行比较
for(int i=0;i<VEC_EDGES.size();i++){
EDGE &edge = VEC_EDGES[i];
V& from = VEC_VS[edge.from-1];
V& to = VEC_VS[edge.to-1];
//如果在MST中
if(MST[edge.from][edge.to]){
t_dis = sum_dis - edge.w;
value = (from.P + to.P)/t_dis;
}else{
//如果不在MST中 则删除路上的最大的权重
memset(VIS,0,sizeof(VIS));
MAX_W = 0;
VEC_PATH.clear();
find_path(edge.from,edge.to);
VEC_PATH.push_back(edge.from);
double max_w = find_max();
t_dis = sum_dis - max_w;
value = (from.P + to.P)/t_dis;
}
if(value > best)
best = value;
}
return best;
}
double solve1(){
double sum_dis = 0;
for(int i=0;i<VEC_MST.size();i++){
sum_dis += VEC_MST[i].w;
}
// for(int i=1;i<=N;i++){
// memset(VIS,0,sizeof(VIS));
// find_max_length(i,i,0);
//
// }
double best = 0,t_dis,value;
//每次从中拿出一条边进行比较
for(int i=0;i<M;i++){
EDGE &edge = EDGES[i];
V& from = VEC_VS[edge.from-1];
V& to = VEC_VS[edge.to-1];
//如果在MST中
if(MST[edge.from][edge.to]){
t_dis = sum_dis - edge.w;
value = (from.P + to.P)/t_dis;
}else{
//如果不在MST中 则删除路上的最大的权重
double max_w = MAX_LENGTH[from.num][to.num];
t_dis = sum_dis - max_w;
value = (from.P + to.P)/t_dis;
}
if(value > best)
best = value;
}
return best;
}
int main()
{
if(DEBUG)
freopen("data.txt","r",stdin);
scanf("%d",&T);
while(T--){
VEC_VS.clear();
VEC_MST.clear();
memset(MAP,0,sizeof(MAP));
memset(MST,0,sizeof(MST));
memset(MAX_LENGTH,0,sizeof(MAX_LENGTH));
memset(SET,0,sizeof(SET));
//memset(MAP,0,sizeof(MAP));
scanf("%d",&N);
int x = 0,y=0,p = 0;
for(int i=1;i<=N;i++){
scanf("%d %d %d",&x,&y,&p);
V v(x,y,p,i);
VEC_VS.push_back(v);
}
//生成边
build_edge();
//生成最小生成树
mst();
//再从所有边中比较
double best = solve1();
printf("%.2f\n",best);
}
return 0;
}