Codeforces Round #397 - E - Tree Folding (找树中直径,dfs)
来源:互联网 发布:比特币交易平台源码 编辑:程序博客网 时间:2024/05/24 00:52
题目链接: Codeforces Round #397 - E - Tree Folding
题意:给定一棵树,每次操作可以选择一个点
解法:先找到树中直径(树中最长路径)的中点,将这个中点当成根,然后通过一次dfs合并所有可以合并的链。最后若得到长度为ans的路径,输出
为什么选中点当根呢?首先如果我们随意选一个点当根的话,可能出现一条可以与其他链合并的链因为被根截断从而导致不能与其他链合并。所以我们要找一个点使得这种链不会被截断。直径的中点就是这样的点。
证明:
假设存在一个点不在直径上,这个点可以引出两条可以合并的链a,b,其中一条链被根截断。那么如果要合并这两条链,要求被截断的一条链a的一部分c要与直径长度的一半相等,使得两个半直径链先合并,再与c合并,从而c的长度与半直径相等,所以a的长度大于c的长度,a+b=2*a的长度大于直径的长度,从而a+b是一条最长链,这与前提矛盾。所以说不存在这样的链a,b。
找树的直径的两个端点两次bfs就行,然后一次dfs找出直径重点,然后一次dfs合并。
#include<bits/stdc++.h>using namespace std;const int maxn=2e5+7;vector<int> adj[maxn],path,a;int l,r;bool vis[maxn];int bfs(int u){ memset(vis,0,sizeof(vis)); int v; queue<int> q; q.push(u);vis[u]=true; while(!q.empty()) { u=q.front();q.pop(); for(int v : adj[u]) { if(vis[v]) continue; q.push(v); vis[v]=true; } } return u;}bool dfs1(int u,int p){ bool flag=false; for(int v : adj[u]) { if(p==v) continue; flag|=dfs1(v,u); } if(u==r) flag=true; if(flag) path.push_back(u); return flag;}int dfs2(int u,int p){ if(adj[u].size()==1) return 1; int res=-1; for(int i=0;i<adj[u].size();i++ ) { int v=adj[u][i]; if(v==p) continue; int tmp=dfs2(v,u); if(tmp==0) return 0; if(res==-1) res=tmp; else if(res!=tmp) return 0; } return res+1;}bool same(const int & t){ for(auto k : a) { if(k==t) return true; } return false;}int f(int k){ while(k%2==0) k>>=1; return k;}int main(){ ios::sync_with_stdio(false);cin.tie(0); int n,u,v; cin>>n; for(int i=1;i<n;i++) { cin>>u>>v; adj[u].push_back(v); adj[v].push_back(u); } l=bfs(1); r=bfs(l); dfs1(l,0); int ct=path[path.size()>>1]; for(auto u : adj[ct]) { int t=dfs2(u,ct); if(t==0) { cout << -1 << endl; return 0; } if(!same(t)) a.push_back(t); } if(a.size()>2) cout<<-1<<endl; else if(a.size()==1) cout<<f(a[0])<<endl; else cout<<f(a[0]+a[1])<<endl; return 0;}
0 0
- Codeforces Round #397 - E - Tree Folding (找树中直径,dfs)
- Codeforces Round #397 E. Tree Folding
- Codeforces Round #397 E. Tree Folding(脑洞)
- Codeforces Round #397 E. Tree Folding (树形dp)
- Codeforces Round #397 Problem E. Tree Folding 解题报告
- Codeforces Round #397 Tree Folding
- Codeforces 765E - Tree Folding 【树,dfs/bfs】
- Codeforces Round #397(Div. 1 + Div. 2 combined)E. Tree Folding【思维+Dfs】dalao们的解法真巧妙系列QAQ
- CodeForces 765E. Tree Folding
- CodeForces 765E. Tree Folding
- Codeforces 734E Anton and Tree (dfs缩点+树的直径)
- Codeforces-734E Anton and Tree(树的直径)
- Codeforces 734E Anton and Tree【并查集缩点||DFS缩点+树的直径】
- Codeforces Round #199 (Div. 2) E. Xenia and Tree (非正规解法 分情况dfs)
- Educational Codeforces Round 6 E. New Year Tree(DFS序+线段树)
- Educational Codeforces Round 6 E. New Year Tree(dfs序线段树)
- Educational Codeforces Round 6 E. New Year Tree(DFS序+线段树)
- codeforces 337E Divisor Tree (dfs)
- 统计一段字符串中单词和字母各出现的次数
- 排序--(单向)冒泡排序
- 关于php缓存技术的简单总结
- 一个可以自由定制外观、支持拖拽消除的MaterialDesign风格Android BadgeView
- 文本处理总结
- Codeforces Round #397 - E - Tree Folding (找树中直径,dfs)
- 为QGroundControl地面站二次开发所做的准备
- mybatis mysql查询结果显示行号
- request和response的理解
- POJ 3503 Summits
- java经典面试题
- ubuntu 命令行卸载并清理软件
- 二叉树的重建
- 走出迷宫