zoukankan      html  css  js  c++  java
  • 藏宝图

     藏宝图

    时间限制: 2 Sec  内存限制: 256 MB

    题目描述

    Czy爬上黑红树,到达了一个奇怪的地方……

    Czy发现了一张奇怪的藏宝图。图上有n个点,m条无向边。已经标出了图中两两之间距离dist。但是czy知道,只有当图刚好又是一颗树的时候,这张藏宝图才是真的。如果藏宝图是真的,那么经过点x的边的边权平均数最大的那个x是藏着宝物的地方。请计算这是不是真的藏宝图,如果是真的藏宝之处在哪里。


    输入

    输入数据第一行一个数T,表示T组数据。

    对于每组数据,第一行一个n,表示藏宝图上的点的个数。

    接下来n行,每行n个数,表示两两节点之间的距离。

    输出

    输出一行或两行。第一行”Yes”或”No”,表示这是不是真的藏宝图。

    若是真的藏宝图,第二行再输出一个数,表示哪个点是藏宝之处。

    样例输入

    2
    3
    0 7 9
    7 0 2
    9 2 0
    3
    0 2 7
    2 0 9
    7 9 0

    样例输出

    Yes
    1
    Yes
    3
    
    样例解释:第一棵树的形状是1--2--3。1、2之间的边权是7,2、3之间是2。
     第二棵树的形状是2--1--3。2、1之间的边权是2,1、3之间是7。

    提示


    对于30%数据,n<=50,1<=树上的边的长度<=10^9。



    对于50%数据,n<=600.



    对于100%数据,1<=n<=2500,除30%小数据外任意0<=dist[i][j]<=10^9,T<=5

       开始就没看懂题目,以为题目中给的是两个点之间直接连边的边权,然后就一直想不出来怎么着就不是一棵树,但其实图中给的是两个点之间的距离,那么,如果他是一棵树的话,这个距离是一定的,不可能存在更短的路径,因为在树中,两个点之间的路径是唯一的,若两个点之间的路径能被其他的点更新,那么就不是一棵树,因为两个点之间存在两条长度不同的路径,那么用prim跑一遍,得出最小生成树,在用这棵树去还原一个新的矩阵,若和原来的矩阵同,则yes,否则no,至于是某个点,随便搞都行

        因为这道题点数比较少,而边很密,所以用Kruska会被卡

      1 #include<cmath>
      2 #include<ctime>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<iostream>
      7 #include<algorithm>
      8 using namespace std;
      9 int T,n;
     10 long long dis[2510][2510];
     11 long long ju[2510];
     12 bool vis[2510];
     13 int fa[2510];
     14 struct node{
     15     int u,v,nxt,w;
     16 }g[5010];
     17 int adj[5010],e;
     18 void add(int u,int v,int w){
     19     g[++e].v=v; g[e].u=u; g[e].w=w;
     20     g[e].nxt=adj[u]; adj[u]=e;
     21 }
     22 void prim(){
     23     ju[1]=0;
     24     for(int i=1;i<=n;i++){
     25         int k=0;
     26         for(int j=1;j<=n;j++){
     27             if(!vis[j] && ju[j]<ju[k])
     28                 k=j;
     29         }
     30         vis[k]=1;
     31         for(int j=1;j<=n;j++){
     32             if(!vis[j] && dis[k][j]<ju[j])
     33                 ju[j]=dis[k][j],fa[j]=k;
     34         }
     35     }
     36 }
     37 long long dis2[2510][2510],ji;
     38 double mx=0;
     39 int sc;
     40 void clear(){
     41     memset(vis,0,sizeof(vis));
     42     memset(ju,0x7f,sizeof(ju));
     43     //cout<<ju[1]<<endl;;
     44     memset(fa,0,sizeof(fa));
     45     e=0; mx=0;
     46     memset(adj,0,sizeof(adj));
     47      
     48 }
     49 void dfs(int x,long long sum,int num){
     50     //cout<<"ji== "<<ji<<"  "<<x<<" "<<sum<<" "<<num<<endl;
     51     dis2[ji][x]=sum;
     52     vis[x]=1;
     53     int chu;
     54     if(x==ji) chu=0;
     55     else chu=1;
     56     double he=(double)num;
     57     for(int i=adj[x];i;i=g[i].nxt){
     58         int v=g[i].v;
     59         if(vis[v]) continue;
     60         chu++;
     61         dfs(v,sum+g[i].w,g[i].w);
     62         he+=g[i].w;
     63     }
     64     he=he/(double)chu;
     65     if(he>mx){
     66         mx=he;
     67         sc=x;
     68     }
     69 }
     70 int main(){
     71     //freopen("a.in","r",stdin);
     72     //freopen("a.out","w",stdout);
     73     scanf("%d",&T);
     74     while(T--){
     75         scanf("%d",&n);
     76         clear();
     77         for(int i=1;i<=n;i++){
     78             for(int j=1;j<=n;j++){
     79                 scanf("%lld",&dis[i][j]);
     80                 //cout<<dis[i][j]<<endl;
     81             }
     82         }
     83         if(n==1){
     84             printf("Yes
    ");
     85             printf("1
    ");
     86             continue;
     87         }
     88         prim();
     89         for(int i=2;i<=n;i++){
     90             add(fa[i],i,ju[i]);
     91             add(i,fa[i],ju[i]);
     92         }
     93         /*
     94         for(int i=1;i<=n;i++){
     95             cout<<"i== "<<i<<" "<<fa[i]<<endl;
     96         }*/
     97         for(int i=1;i<=n;i++){
     98             memset(vis,0,sizeof(vis));
     99             vis[i]=1; ji=i;
    100             dfs(i,0,0);
    101         }
    102         //while(1);
    103         bool ok=1;
    104         for(int i=1;i<=n;i++){
    105             for(int j=1;j<=n;j++){
    106                 if(dis2[i][j] != dis[i][j]) ok=0;
    107             }
    108         }
    109         if(!ok){
    110             printf("No
    ");
    111         }
    112         else{
    113             printf("Yes
    ");
    114             printf("%d
    ",sc);
    115         }
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7258161.html
Copyright © 2011-2022 走看看