2019牛客多校第四场 A meeting

链接:https://ac.nowcoder.com/acm/contest/884/A
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

A new city has just been built. There're nnn interesting places numbered by positive numbers from 111 to nnn.
In order to save resources, only exactly n−1n-1n1 roads are built to connect these nnn interesting places. Each road connects two places and it takes 1 second to travel between the endpoints of any road.
There is one person in each of the places numbered x1,x2…xkx_1,x_2 ldots x_kx1,x2xk and they've decided to meet at one place to have a meal. They wonder what's the minimal time needed for them to meet in such a place. (The time required is the maximum time for each person to get to that place.)

输入描述:

First line two positive integers, n,kn,kn,k - the number of places and persons.
For each the following n−1n-1n1 lines, there're two integers a,ba,ba,b that stand for a road connecting place aaa and bbb. It's guaranteed that these roads connected all nnn places.
On the following line there're kkk different positive integers x1,x2…xkx_1,x_2 ldots x_kx1,x2xk separated by spaces. These are the numbers of places the persons are at.

输出描述:

A non-negative integer - the minimal time for persons to meet together.
示例1

输入

复制
4 2
1 2
3 1
3 4
2 4

输出

复制
2

说明

They can meet at place 1 or 3.
1<=n<=1e5

题意

给出一颗树和一些点,一个点到另一个点的距离为1,求这些点在树上最大距离的一半

思路
要求图上的最大距离可先任意取一个点求最大距离,再从最大距离的这个点再找一次最大距离(因为重新求的最大距离必定大于或等于原先的最大距离)
这里求最大距离用了边权取负再dijkstra,把求出的最小负距离取反就得到最大正距离

代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int amn=2e5+5,inf=0x3f3f3f3f;
 4 int n,k,dis[amn];
 5 int p[amn];
 6 struct node{
 7     int pos,val;
 8     bool operator <(const node &a)const {return a.val<val;}
 9 };
10 struct edge{
11     int to,w,next;
12 }e[amn];
13 priority_queue<node> que;
14 int head[amn],edgenum=0,vis[amn];
15 void add(int f,int t,int co)
16     {
17         e[++edgenum].next=head[f];
18         head[f]=edgenum;
19         e[edgenum].to=t;
20         e[edgenum].w=co;
21     }
22 void Dijkstra(int s)
23     {
24         memset(dis,0x3f,sizeof(dis));
25         memset(vis,0,sizeof vis);
26         while(que.size())que.pop();
27         dis[s]=0;
28         node a;
29         a.pos=s,a.val=dis[s];
30         que.push(a);
31         while(!que.empty())
32             {
33                 node x=que.top();que.pop();
34                 int u = x.pos;
35                 if(x.val > dis[u]) continue;
36                 vis[u]=true;
37                 for(int i=head[u];i!=-1;i=e[i].next)
38                     {
39                         int v=e[i].to;
40                         if(vis[v])    continue;
41                         if(dis[v]>e[i].w+dis[u])
42                             {
43                                 dis[v]=e[i].w + dis[u];
44                                 a.pos=v,a.val=dis[v];
45                                 que.push(a);
46                             }
47                     }
48             }
49     }
50 int main(){
51     memset(head,-1,sizeof head);
52     ios::sync_with_stdio(0);
53     cin>>n>>k;
54     int u,v,ans;
55     for(int i=1;i<n;i++){
56         cin>>u>>v;
57         add(u,v,-1);
58         add(v,u,-1);
59     }
60     for(int i=1;i<=k;i++){
61         cin>>p[i];
62     }
63     Dijkstra(p[1]);
64     int maxn=inf,maxi=0;
65     for(int i=1;i<=k;i++){
66         if(dis[p[i]]<maxn){
67             maxn=dis[p[i]];
68             maxi=i;
69         }
70     }
71     Dijkstra(p[maxi]);
72     ans=inf;
73     for(int i=1;i<=k;i++){
74         if(dis[p[i]]<ans){
75             ans=dis[p[i]];
76         }
77     }
78     ans=-ans;
79     printf("%d
",ans/2+ans%2);
80 }


 
原文地址:https://www.cnblogs.com/Railgun000/p/11257119.html