zoukankan      html  css  js  c++  java
  • 洛谷P1395 会议(CODEVS.3029.设置位置)(求树的重心)

    To 洛谷.1395 会议 To CODEVS.3029 设置位置

    题目描述

    有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1。现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地点设置在哪个村民的家中,并且这个距离总和最小是多少?若有多个节点都满足条件,则选择节点编号最小的那个点。

    输入输出格式

    输入格式:

    第一行。一个数n,表示有n个村民。

    接下来n-1行,每行两个数字a和b,表示村民a的家和村民b的家之间存在一条路径。

    输出格式:

    一行输出两个数字x和y

    x表示村长将会在哪个村民家中举办会议

    y表示距离之和的最小值

    输入输出样例

    输入样例#1:
    4
    1 2 
    2 3 
    3 4 
    
    输出样例#1:
    2 4

    说明

    【数据范围】

    70%数据n<=1000

    100%数据n<=50000

    思路:

      求树的重心,然后求重心到每个点的距离。(树的重心 百度百科

      如果用n遍spfa会超时。

    代码:

    1.dfs

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=50005,INF=0x3f3f3f3f;
     6 
     7 int n,cnt,Ans,Min,size=INF,H[N<<1],son[N],dep[N];
     8 bool vis[N];
     9 struct Edge
    10 {
    11     int to,nxt;
    12 }e[N<<1];
    13 
    14 void read(int &now)
    15 {
    16     now=0;bool f=0;char c=getchar();
    17     while(c>'9'||c<'0')
    18     {
    19         if(c=='-')f=1;
    20         c=getchar();
    21     }
    22     while(c>='0'&&c<='9')now=(now<<3)+(now<<1)+c-'0',c=getchar();
    23     now= f?-now:now;
    24 }
    25 
    26 void AddEdge(int u,int v)
    27 {
    28     e[++cnt].to = v;
    29     e[cnt].nxt = H[u];
    30     H[u] = cnt;
    31 }
    32 
    33 void DFS(int cur)
    34 {//求树的重心 
    35     vis[cur]=1;
    36     son[cur]=0;
    37     int tmp=0;
    38     for(int i=H[cur];i;i=e[i].nxt)
    39     {
    40         if(!vis[e[i].to])
    41         {
    42             DFS(e[i].to);
    43             son[cur]+=son[e[i].to]+1;
    44             tmp=max(tmp,son[e[i].to]+1);
    45         }
    46     }
    47     tmp=max(tmp,n-son[cur]-1);
    48     if(size>tmp || tmp==size&&Ans>cur)
    49     {
    50         Ans=cur;
    51         size=tmp;
    52     }
    53 }
    54 
    55 void DFSforDeep(int x,int y,int d)
    56 {
    57     dep[x]=d;
    58     for(int i=H[x];i;i=e[i].nxt)
    59       if(y != e[i].to)
    60         DFSforDeep(e[i].to,x,d+1);
    61 }
    62 
    63 int main()
    64 {
    65     read(n);
    66     int x,y;
    67     for(int i=1;i<n;++i)
    68     {
    69         read(x);read(y);
    70         AddEdge(x,y);
    71         AddEdge(y,x);
    72     }
    73     DFS(1);
    74     DFSforDeep(Ans,Ans,0);
    75     for(int i=1;i<=n;++i)
    76       Min+=abs(dep[Ans]-dep[i]);
    77     printf("%d %d",Ans,Min);    
    78     return 0;
    79 }
    AC

    2.70分的spfa

     1 #include<queue>
     2 #include<cstdio>
     3 using namespace std;
     4 const int N=50005,INF=0x3f3f3f3f;
     5 
     6 int n,cnt,Ans,Min=INF,H[N<<1],Dist[N];
     7 bool Exist[N];
     8 queue<int>q;
     9 struct Edge
    10 {
    11     int to,nxt;
    12 }e[N<<1];
    13 
    14 void read(int &now)
    15 {
    16     now=0;bool f=0;char c=getchar();
    17     while(c>'9'||c<'0')
    18     {
    19         if(c=='-')f=1;
    20         c=getchar();
    21     }
    22     while(c>='0'&&c<='9')now=(now<<3)+(now<<1)+c-'0',c=getchar();
    23     now= f?-now:now;
    24 }
    25 
    26 void AddEdge(int u,int v)
    27 {
    28     e[++cnt].to = v;
    29     e[cnt].nxt = H[u];
    30     H[u] = cnt;
    31 }
    32 
    33 void spfa(int x)
    34 {
    35     for(int i=1;i<=n;++i)
    36       Exist[i]=0,Dist[i]=INF;
    37     Dist[x]=0;
    38     Exist[x]=1;
    39     q.push(x);
    40     while(!q.empty())
    41     {
    42         int cur=q.front();
    43         q.pop();
    44         Exist[cur]=0;
    45         for(int i=H[cur];i;i=e[i].nxt)
    46         {
    47             int to=e[i].to;
    48             if(Dist[to]<=Dist[cur]+1)continue;
    49             Dist[to]=Dist[cur]+1;
    50             if(!Exist[to])
    51               q.push(to),Exist[to]=1;
    52         }
    53     }
    54 }
    55 
    56 int main()
    57 {
    58     read(n);
    59     int x,y;
    60     for(int i=1;i<n;++i)
    61     {
    62         read(x);read(y);
    63         AddEdge(x,y);
    64         AddEdge(y,x);
    65     }
    66     for(int i=1;i<=n;++i)
    67     {
    68         spfa(i);
    69         int sum=0;bool OK=1;
    70         for(int j=1;j<=n;++j)
    71           if(Dist[j]==INF)
    72           {
    73                 OK=0;break;//防止累加INF溢出,不知道有没有用 
    74           }
    75           else
    76             sum+=Dist[j];
    77         if(sum<Min && OK)
    78           Min=sum,Ans=i;
    79     }
    80     printf("%d %d",Ans,Min);    
    81     return 0;
    82 }
    TLE
  • 相关阅读:
    异常问题处理记录(转载篇)
    linux服务器出现大量连接:sshd: root@notty
    第4章 Python运算符
    第2章 python基础知识
    第1章 python环境搭建
    Tomcat漏洞升级
    第3章 数据类型、运算符和表达式
    第2章 C语言基础知识
    第1章 概述
    第1章 企业管理概论
  • 原文地址:https://www.cnblogs.com/SovietPower/p/6897901.html
Copyright © 2011-2022 走看看