牛客 病毒感染 ###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 }

浙公网安备 33010602011771号