https://vjudge.net/problem/UVALive-5713
首先明确题意
①希望使n个城市联通且道路最短
②可以修一条魔法道路不花钱
③设A为魔法道路连接的两座城市的人口之和,B为总花费,希望使得A/B最大
就是非严格次小生成树
又被double锤爆了呜呜呜
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cstring> #include<cmath> #define ri register int #define u int #define NN 1005 #define MM 1005*1005 namespace fast { inline u in() { u x(0); char s=getchar(); while(s<'0'||s>'9') { s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x; } } using fast::in; using std::queue; using std::pair; namespace cas { u fa[NN]; inline u getfa(u x) { u r(x),k; while(fa[r]^r) { r=fa[r]; } while(x^r) { k=x,x=fa[x],fa[k]=r; } return r; } inline void pri(const u &n) { for(ri i=1; i<=n; ++i)fa[i]=i; } } using namespace cas; namespace all { u N,M,T,cnt,h[NN]; struct node { u to,next; double va; } a[MM]; inline void add(const u &x,const u &y,const double &z) { a[++cnt].next=h[x],a[cnt].to=y,a[cnt].va=z,h[x]=cnt; } struct node1 { u x,y,z; } b[NN]; u num,n; struct node2 { u x,y; double z; } c[MM]; double calc(const double &x,const double &y,const double &xx,const double &yy) { return std::sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy)); } bool cmp(const node2 &x,const node2 &y) { return x.z<y.z; } double m[NN][NN],g[NN][NN]; double dfs(const u &x,const u &y,const u &prt,double mi) { if(g[x][y]) return g[x][y]; if(x^y) { double _re; for(ri i(h[x]); i; i=a[i].next) { u _y(a[i].to); if(_y==prt) continue; _re=std::max(mi,a[i].va); double _r=dfs(_y,y,x,_re); if(_r>0) { return _r; } } return 0; } else { return mi; } } inline void solve() { T=in(); while(T--) { n=num=cnt=0; std::memset(h,0,sizeof(h)); std::memset(m,0,sizeof(m)); std::memset(g,0,sizeof(g)); N=in(); for(ri i(1); i<=N; ++i) { u _x(in()),_y(in()),_z(in()); b[i].x=_x,b[i].y=_y,b[i].z=_z;//点 坐标,人数 } for(ri i(1); i<=N; ++i) { for(ri j(1); j<=N; ++j) { if(i^j) { c[++num].x=i,c[num].y=j; c[num].z=calc((double)b[i].x,(double)b[i].y,(double)b[j].x,(double)b[j].y);//边 两点,距离 } } } std::sort(c+1,c+num+1,cmp); u _cnt(0); double ans(0.0); pri(N); while(n<N-1) { u fx(getfa(c[++_cnt].x)),fy(getfa(c[_cnt].y)); if(fx^fy) { fa[fx]=fy,++n,ans+=c[_cnt].z; add(c[_cnt].x,c[_cnt].y,c[_cnt].z); add(c[_cnt].y,c[_cnt].x,c[_cnt].z); m[c[_cnt].x][c[_cnt].y]=m[c[_cnt].y][c[_cnt].x]=c[_cnt].z; } } double as(0); for(ri i(1); i<=N; ++i) { for(ri j(i+1); j<=N; ++j) { double _a(b[i].z+b[j].z),_b(ans); if(m[i][j]) { _b-=m[i][j]; } else { _b-=(g[i][j]=g[j][i]=dfs(i,j,0,0)); } as=std::max(as,_a/_b); /*if(as>6.324) { u _p(0); }*/ } } printf("%.2lf\n",as); } } } int main() { //freopen("x.txt","r",stdin); all::solve(); }