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 }