codeForces 472D 最小生成树

来源:互联网 发布:处理器加速优化 编辑:程序博客网 时间:2024/06/07 11:09

题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点

prim最小生成树,若原图是树,则最小生成树的距离就是原距离。否则不是。

搞出来树了,第二问随便dfs就好了。

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#define N 2550using namespace std;int T,n,fa[N],pp[N];long long dis[N][N],minn[N],a[N][N],ans,num;bool boo;double maxn;int final;int head[N],e=1;struct edge{    int u,v,w,next;}ed[2*N];void add(int u,int v,int w){    ed[e].u=u; ed[e].v=v; ed[e].w=w;    ed[e].next=head[u]; head[u]=e++;}bool bo[N];void dfs(int x,int now,long long d){    if(bo[now])return;    bo[now]=1;    dis[x][now]=d;    for(int i=head[now];i;i=ed[i].next)        dfs(x,ed[i].v,d+ed[i].w);}int main(){    //freopen("treas.in","r",stdin);    //freopen("treas.out","w",stdout);    scanf("%d",&T);    while(T--){        memset(head,0,sizeof head); e=1;        memset(bo,0,sizeof bo);        memset(minn,0x7f,sizeof minn);        scanf("%d",&n); boo=0;        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                scanf("%lld",&a[i][j]);        for(int i=1;i<=n;i++){            minn[i]=a[1][i];            pp[i]=1;        }        bo[1]=1; fa[1]=0;        for(int i=1;i<n;i++)        {            int now=0;            for(int j=1;j<=n;j++)                if(!bo[j]&&minn[j]<minn[now])                    now=j;            bo[now]=1; fa[now]=pp[now];            add(pp[now],now,a[pp[now]][now]);            add(now,pp[now],a[now][pp[now]]);            for(int j=1;j<=n;j++)                if(!bo[j]&&a[now][j]<minn[j]){                    minn[j]=a[now][j];                    pp[j]=now;                }        }        //for(int i=1;i<=n;i++)            //printf("%d  %d\n",i,fa[i]);        for(int i=1;i<=n;i++){            memset(bo,0,sizeof(bo));            dfs(i,i,0);        }        for(int i=1;i<=n;i++){            for(int j=1;j<=n;j++){                //printf("%lld ",dis[i][j]);                if(a[i][j]!=dis[i][j]){                    boo=1; break;                }            }if(boo==1) break;             //printf("\n");        }if(boo==1){printf("No\n"); continue;}        maxn=0; final=1;        for(int i=1;i<=n;i++){            num=ans=0;            for(int j=head[i];j;j=ed[j].next){                num++;                                      ans+=ed[j].w;                             }            if((double)(1.0*ans)/(1.0*num)>maxn){                final=i;                maxn=(double)(1.0*ans)/(1.0*num);            }        }        printf("Yes\n%d\n",final);    }}


阅读全文
0 0