Gym-100781A 【树的直径 + 思维】
2017-10-08 20:28
357 查看
传送门
//题意: 给你很多颗树(当然也可能只有一棵树), 问你怎样连接起来可以使得形成的树上最远的距离最小,并输出这个距离.
//思路: 当然是和树的直径有关, 然后可以知道从直径折半的地方连出去是最优的, 先用并查集求出每一棵树的直径. 然后需要讨论几种情况, 一是有一棵树它的直径本来就很长, 那么答案有可能是它, 然后(必须两棵树以上)就是直径第一长的和第二长的, 可能是一种答案, 还有一种就是(必须三棵树以上)以直径最长的树作为中转点, 第二长的和第三长的通过这个相连, 那么答案也可能是这种情况最优, 如果你要问为什么不以第三长的作为中转点的话, 那就是没懂起题意, 要让最远的距离最小, 所以只能这样, 细节请看代码.
AC Code
//题意: 给你很多颗树(当然也可能只有一棵树), 问你怎样连接起来可以使得形成的树上最远的距离最小,并输出这个距离.
//思路: 当然是和树的直径有关, 然后可以知道从直径折半的地方连出去是最优的, 先用并查集求出每一棵树的直径. 然后需要讨论几种情况, 一是有一棵树它的直径本来就很长, 那么答案有可能是它, 然后(必须两棵树以上)就是直径第一长的和第二长的, 可能是一种答案, 还有一种就是(必须三棵树以上)以直径最长的树作为中转点, 第二长的和第三长的通过这个相连, 那么答案也可能是这种情况最优, 如果你要问为什么不以第三长的作为中转点的话, 那就是没懂起题意, 要让最远的距离最小, 所以只能这样, 细节请看代码.
AC Code
const int maxn = 1e5+5; int cas=1; int pre[maxn],vis[maxn]; int n,m; vector<int>g[maxn]; int Find(int x) { return pre[x] == x?x: pre[x] = Find(pre[x]); //不要再写成 == 了!!! } int maxx; int dfs(int u,int fa) { int fir = 0, sec = 0; for(int i=0;i<g[u].size();i++){ int to = g[u][i]; if(to == fa) continue; int tmp = dfs(to,u); if(tmp > fir) sec = fir, fir = tmp; else if(tmp > sec) sec = tmp; } if(fir + sec > maxx) maxx = fir + sec; return fir + 1; } int d[maxn]; bool cmp(int a,int b) { return a > b; } void solve() { while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++) g[i].clear(),pre[i] = i; Fill(vis,0); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); u++; v++; g[u].push_back(v); g[v].push_back(u); u = Find(u); v = Find(v); if(u != v) pre[u] = v; } int idx = 0 ; for(int i=1;i<=n;i++){ //并查集求每棵树的直径. if(vis[Find(i)]) continue; vis[Find(i)] = 1; maxx = 0; dfs(i,-1); d[idx++] = maxx; } sort(d,d+idx,cmp); int res = d[0]; //第一种情况 if(idx > 1){ //第二种情况 res = max(res,(d[0] + 1)/2 + (d[1] + 1)/2 + 1); } if(idx > 2){ //第三种情况 res = max(res,(d[1] + 1)/2 + (d[2] + 1)/2 + 2); } printf("%d\n",res); } }
相关文章推荐
- codeforces GYM 100781A【树的直径】
- 【DFS】Gym - 100781A - Adjoin the Networks
- Gym 100712H(边双联通+树的直径)
- codeforces GYM 100114 J. Computer Network tarjan 树的直径 缩点
- GYM 101243 F.Vitamins【思维+并查集】
- Gym 101142G Gangsters in Central City【思维+Lca】
- 【思维 && 几何】Gym - 101063K Dire, Dire Docks
- 思维-Gym - 101341B-好题(5-5-B)
- Gym 100712H(边双联通+树的直径)
- Gym - 101246H ``North-East''【思维+nlogn LIS】
- Gym - 101522B树的直径
- Gym - 100676H Capital City(边强连通分量 + 树的直径)
- Gym 100712H(边双联通+树的直径)
- UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
- Problem D. Dales and Hills - Gym - 101411D 【动态规划经典题 - 思维】
- Gym 101470J Stange Antennas【思维】
- Gym - 100676H H. Capital City (边双连通分量缩点+树的直径)
- 江苏省赛 --- H题 【树的直径+思维】
- Gym 100712H(边双联通+树的直径)
- 思维题 Gym 100553A Alter Board