1. 程式人生 > >【NOIP模擬賽】藏寶圖 最小生成樹

【NOIP模擬賽】藏寶圖 最小生成樹

names pri double span -- string noip getchar n!

性質:我們把最小生成樹建出來,如果其距離符合那麽就是對的,不符合就是錯的

因為這是個n^2的圖所以不能Kruskal只能Prim

#include <cstdio>
#include <cstring>
#include <iostream>
#define N 2500
#define R register
using namespace std;
typedef double DO;
inline long long read()
{
    long long sum=0;
    char ch=getchar();
    while(ch<0
||ch>9)ch=getchar(); while(ch>=0&&ch<=9) { sum=(sum<<1)+(sum<<3)+ch-0; ch=getchar(); } return sum; } struct V { long long to,next,w; }c[N<<1]; long long head[N+10],t; long long dis[N+10][N+10],get[N+10][N+10]; DO Ans[N+10]; bool v[N+10
]; long long T,n; long long Dis[N+10],Min; long long ans; inline void add(long long x,long long y,long long z) { c[++t].to=y; c[t].next=head[x]; c[t].w=z; head[x]=t; } inline long long Prim() { memset(head,0,sizeof(head)); memset(v,0,sizeof(v)); memset(Dis,0,sizeof(Dis)); Dis[
1]=1; t=0; Min=0; R long long B=n; while(B--) { for(R long long i=1;i<=n;i++) if(v[i]==0&&dis[Dis[i]][i]<dis[Dis[Min]][Min]) Min=i; v[Min]=1; if(Min!=1) { add(Dis[Min],Min,dis[Dis[Min]][Min]); add(Min,Dis[Min],dis[Dis[Min]][Min]); } for(R long long i=1;i<=n;i++) if(v[i]==0&&dis[Dis[i]][i]>dis[Min][i]) Dis[i]=Min; Min=0; } } void dfs(long long x,long long r,long long fa,long long D) { get[r][x]=D; for(R long long i=head[x];i;i=c[i].next) if(c[i].to!=fa) dfs(c[i].to,r,x,D+c[i].w); } inline bool Go_Die() { for(R long long i=1;i<=n;i++) dfs(i,i,0,0); for(R long long i=1;i<=n;i++) for(R long long j=1;j<=n;j++) if(get[i][j]!=dis[i][j]) return 1; return 0; } void Dfs(long long x,long long fa) { R long long TT=0; for(R long long i=head[x];i;i=c[i].next) { ++TT; Ans[x]+=c[i].w; if(c[i].to!=fa) Dfs(c[i].to,x); } Ans[x]/=TT; if(Ans[x]>Ans[ans])ans=x; } int main() { T=read(); Ans[0]=-1.0; for(R int i=0;i<N+10;i++)dis[0][i]=100000000000000LL; while(T--) { n=read(); ans=0; for(R long long i=1;i<=n;i++) for(R long long j=1;j<=n;j++) dis[i][j]=read(); if(n==1) { printf("Yes\n1\n"); continue; } Prim(); if(Go_Die())printf("No\n"); else { for(R long long i=1;i<=n;i++)Ans[i]=0.0; Dfs(1,0); printf("Yes\n"); printf("%d\n",ans); } } }

【NOIP模擬賽】藏寶圖 最小生成樹