zoukankan      html  css  js  c++  java
  • codeForces 472D 最小生成树

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

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

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

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #define N 2550
    using 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
    ",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("
    ");
            }if(boo==1){printf("No
    "); 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
    %d
    ",final);
        }
    }


  • 相关阅读:
    3.12
    3.11
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746730.html
Copyright © 2011-2022 走看看