ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)K Kingdom Roadmap

K:

  给你n个点以及n-1的条边, 问你最少要加多少条边,使得每两个点割去一条联通的边,还可以使的这两个点连通。

  有个一个结论,最少添加的边数为(叶子节点数+1)/ 2。 

  我们可以只考虑叶子节点数应该怎么连了。按dfs序标号

  a0 连 an/2  , a2连an/2+1  ·····。如果是奇数个,就把an连a1。

  因为a0可以和别的节点连接,但是怎么样才是最好的,要每一个圈都尽量相交。

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 typedef unsigned long long uLL;
15 #define ms(a, b) memset(a, b, sizeof(a))
16 #define pb push_back
17 #define mp make_pair
18 #define eps 0.0000000001
19 #define IOS ios::sync_with_stdio(0);cin.tie(0);
20 const LL INF = 0x3f3f3f3f3f3f3f3f;
21 const int inf = 0x3f3f3f3f;
22 const int maxn = 2e5+10;
23 const int mod = 1e9+7;
24 vector <int> T[maxn];
25 int ans[maxn], cnt = 0;
26 void dfs(int fa, int x)
27 {
28     if(T[x].size()==1)  ans[cnt++] = x;
29     for(int i = 0;i<T[x].size();i++){
30         if(T[x][i]!=fa)
31             dfs(x, T[x][i]);
32     }
33 }
34 int main()
35 {
36 #ifdef LOCAL
37     freopen("input.txt", "r", stdin);
38 //    freopen("output.txt", "w", stdout);
39 #endif
40 
41     freopen("kingdom.in", "r", stdin);
42     freopen("kingdom.out", "w", stdout);
43 
44     int n, u, v;
45     scanf("%d", &n);
46     for(int i = 0;i<n-1;i++){
47         scanf("%d%d", &u, &v);
48         T[u].pb(v);
49         T[v].pb(u);
50     }
51     dfs(-1, 1);
52     printf("%d\n", (cnt+1)/2);
53 //    for(int i = 0;i<cnt;i++){
54 //        printf("%d ", ans[i]);
55 //    }
56     for(int i = 0;i<cnt/2;i++){
57         printf("%d %d\n", ans[i], ans[cnt/2+i]);
58     }
59     if(cnt&1)   printf("%d %d\n", ans[cnt-1], ans[0]);
60     return 0;
61 }
View Code

 

  

posted @ 2017-08-26 20:42  Dh_q  阅读(143)  评论(0编辑  收藏  举报