首页 > 代码库 > 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(树上最长路径)