CodeForces
来源:互联网 发布:美国 贫富差距 知乎 编辑:程序博客网 时间:2024/05/29 14:08
题目地址:http://codeforces.com/problemset/problem/748/F
思路:由于整个结构为树,则每个点之间的最短路径唯一,则可以发现住宿处个数存在且最小为1。则住宿处为某一点将所有team分成两部分且在所有配对的team的最短路上,则住宿处的位置为某子树中包含家乡的点的个数不小于k的最小子树的根节点。则分队可以将该子树的两部分直接分配:dfs过程中将家乡加入左边部分,当左边部分个数等于k时,开始将点加入右边部分,最后将左边与右边的点输出即可(住宿处作为根节点将所有家乡分成两部分,所以住宿处必在所有点之间的最短路上,所以可以直接分配)。
#include<cstdio>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#define debuusing namespace std;const int maxn=2e5+50;int vis[maxn];int n,k,root,sum;int home[maxn];vector<int> one,two;vector<int> g[maxn];int find_Root(int u){ int sum=home[u]?1:0; for(int i=0; i<g[u].size(); i++) { int nt=g[u][i]; if(!vis[nt]) { vis[nt]=1; sum+=find_Root(nt); } } if(sum>=k&&root==-1) root=u; return sum;}void solve(int u){ if(home[u]) { if(one.size()<k) one.push_back(u); else two.push_back(u); } for(int i=0; i<g[u].size(); i++) { int nt=g[u][i]; if(!vis[nt]) { vis[nt]=1; solve(nt); } }}int main(){#ifdef debug freopen("in.in","r",stdin);#endif // debug scanf("%d%d",&n,&k); for(int i=0; i<n-1; i++) { int u,v; scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } for(int i=0; i<2*k; i++) { int x; scanf("%d",&x); home[x]=1; } memset(vis,0,sizeof(vis)); vis[1]=1,root=-1; find_Root(1); memset(vis,0,sizeof(vis)); vis[root]=1; solve(root); printf("1\n%d\n",root); for(int i=0; i<one.size(); i++) printf("%d %d %d\n",one[i],two[i],root); return 0;}
0 0
- codeforces~~~
- Codeforces
- codeforces
- Codeforces
- codeforces
- codeforces
- Codeforces
- Codeforces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- CodeForces
- 学习linux commands:export
- 有关opencv的学习(4)—图像的锐化
- Intent中显示意图和隐式意图
- 天地图再次使用体验(2017.3.4)
- CodeForces
- 004.PHP实现快速排序
- 第六届蓝桥杯省赛Java语言C组_移动距离
- Laravel 开发笔记
- 别人问你AIDL,我来给你回答
- JavaScript 变量/命名规则/交换两个数值类型的变量
- NO2.week2
- Linxu启动过程
- 主题模型