首页 > 代码库 > Codefroces Gym 100781A(树上最长路径)
Codefroces Gym 100781A(树上最长路径)
http://codeforces.com/gym/100781/attachments
题意:有N个点,M条边,问对两两之间的树添加一条边之后,让整棵大树最远的点对之间的距离最近,问这个最近距离是多少。
思路:一开始看成只有两个连通块,后来才注意到是多个连通块。DFS搜树上最长路径。答案有三种:第一种是添加了边之后,树的最长路径还是原来子树的路径,第二种是对子树长度进行排序后,两个最长的距离分别除以2向上取整后加上1。第三种比较难注意到,就是第二第三长的分别除以2向上取整后加上2,因为可能隔着一条边之后比第一种情况更长了。
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <queue> 8 #include <vector> 9 using namespace std;10 #define N 10001011 struct node12 {13 int v, nxt;14 }edge[N*2];15 int head[N], tot;16 bool vis[N];17 int ans[N];18 int l;19 20 void add(int u, int v)21 {22 edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;23 }24 25 bool cmp(const int &a, const int &b)26 {27 return a > b;28 }29 30 int dfs(int u)31 {32 vis[u] = 1;33 int m1 = 0, m2 = 0;34 for(int i = head[u]; ~i; i = edge[i].nxt) {35 int v = edge[i].v;36 if(vis[v]) continue;37 int tmp = dfs(v) + 1;38 if(tmp > m1) {39 m2 = m1, m1 = tmp;40 } else if(tmp > m2) {41 m2 = tmp;42 }43 }44 if((m1 + m2) > l) l = m1 + m2;45 return m1;46 }47 48 int main()49 {50 int n, m;51 scanf("%d%d", &n, &m);52 memset(vis, 0, sizeof(vis));53 memset(head, -1, sizeof(head));54 memset(ans, 0, sizeof(ans));55 tot = 0;56 for(int i = 0; i < m; i++) {57 int u, v;58 scanf("%d%d", &u, &v);59 add(u, v); add(v, u);60 }61 int cnt = 0, res = 0;62 for(int i = 0; i < n; i++) {63 if(!vis[i]) {64 l = 0;65 dfs(i); //搜树上最长路径66 if(l > res) res = l; //第一种情况67 ans[cnt++] = l;68 }69 }70 sort(ans, ans + cnt, cmp);71 if(cnt > 1) res = max(res, (ans[0] + 1) / 2 + (ans[1] + 1) / 2 + 1); //第二种情况72 if(cnt > 2) res = max(res, (ans[1] + 1) / 2 + (ans[2] + 1) / 2 + 2); //第三种情况73 printf("%d\n", res);74 return 0;75 }
Codefroces Gym 100781A(树上最长路径)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。