牛客 病毒感染 ###K ###K ###K //K

题目链接:https://ac.nowcoder.com/acm/contest/6173/B

思路:根据题意 求的其实是树的重心  利用的性质是 求出当前的节点下 所有的子节点中,子节点数最大的那个,   这个数最小的就是重心

一棵树最多有两个重心,且相邻     树的重心资料:https://oi-wiki.org/graph/tree-centroid/    https://baike.baidu.com/item/%E6%A0%91%E7%9A%84%E9%87%8D%E5%BF%83/20416316?fr=aladdin

n-子树的和 就为 该点上方的子树的数量   处理的时候必须在dfs中处理  单独for处理 会处理到父节点

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=2e5+10;
 7 const int mod=1e9+7;
 8 map<int,map<int,int>>mp;
 9 vector<int>E[maxn];
10 vector<int>ans;
11 int cnt[maxn];
12 int min1=1e9;
13 int n;
14 
15 
16 void dfs(int u,int fa)
17 {
18     cnt[u]=1;
19     int r=0;
20     for(auto &v:E[u])
21     {
22         if(v==fa)
23             continue;
24         dfs(v,u);
25         cnt[u]+=cnt[v];
26         r=max(r,cnt[v]);
27     }
28     r=max(r,n-cnt[u]);
29     if(r==min1)
30     {
31         ans.pb(u);
32     }
33     if(r<min1)
34     {
35         min1=r;
36         ans.clear();
37         ans.pb(u);
38     }
39 
40 }
41 
42 
43 int main()
44 {
45     ios::sync_with_stdio(false);
46     cin.tie(0);
47     int m;
48     cin>>n>>m;
49     while(m--)
50     {
51         int u,v;
52         cin>>u>>v;
53         if(mp[u][v])
54             continue;
55         mp[u][v]=1,mp[v][u]=1;
56         E[u].pb(v);
57         E[v].pb(u);
58     }
59     dfs(1,0);
60     for(auto &v:ans)
61         cout<<v<<" ";
62 
63 
64 }
View Code

 

posted @ 2020-07-08 14:45  canwinfor  阅读(201)  评论(0)    收藏  举报