CodeForces 618D Hamiltonian Spanning Tree
题意:要把所有的节点都访问一次,并且不能重复访问,有两种方式访问,一种是根据树上的路径
走和当前节点连接的下一个节点cost x, 或者可以不走树上边,直接跳到不与当前节点连接的节点,cost y
分析:
别被树吓着!
一定会走n-1条路,那么就是有一些走树上的边,有一些不走。
如果树上的路径cost更大(x >= y),那么尽可能的不走树上的路径,那么根据尝试可以找到规律
如果有一个节点是所有节点的父节点,也就是说这个节点的度为n-1,那么只会走一个x其他都是y
如果没有这个节点,一定可以全部走y
另一种情况如果(x < y),那么也就是说要尽可能的多走树上的边,我们知道一个节点只能访问一次,也就是说
一个节点最多只能连两条边出去,然后dfs搜索,找到最多可以走多少条,每个节点的度数如果不被剪完就可以继续连,
剩下的只能走y。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <queue> 5 #include <vector> 6 #include <algorithm> 7 #include <stack> 8 #include <set> 9 #include <map> 10 #include <math.h> 11 #define pb push_back 12 #define CLR(a) memset(a, 0, sizeof(a)); 13 #define MEM(a, b) memset(a, b, sizeof(a)); 14 #define fi first 15 #define se second 16 17 using namespace std; 18 19 typedef long long ll; 20 21 const int MAXN = 200007; 22 const int MAXV = 207; 23 const int MAXE = 207; 24 const int INF = 0x3f3f3f3f; 25 ll x, y, n; 26 struct Edge 27 { 28 int to, next; 29 Edge () {} 30 Edge(int to, int next) : to(to), next(next) {} 31 }edge[MAXN << 1]; 32 int num; 33 int head[MAXN]; 34 void Add(int from, int to) 35 { 36 edge[num] = Edge(to, head[from]); 37 head[from] = num++; 38 } 39 int deg[MAXN]; 40 ll ans = 0; 41 ll len = 0; 42 int cnt = 0; 43 bool dfs(int crt, int fa) 44 { 45 int rem = 2; 46 for (int t = head[crt]; t != -1; t = edge[t].next) 47 { 48 Edge e = edge[t]; 49 int v = e.to; 50 if (v == fa) continue; 51 if (dfs(v, crt) && rem > 0) 52 { 53 len++; rem--; 54 } 55 } 56 return rem > 0; 57 } 58 59 int main() 60 { 61 //freopen("in.txt", "r", stdin); 62 while (~scanf("%lld%lld%lld", &n, &x, &y)) 63 { 64 MEM(head, -1); 65 MEM(edge, -1); 66 CLR(deg); 67 num = 0; 68 len = 0; 69 for (int i = 0; i < n-1; i++) 70 { 71 int u, v; 72 scanf("%d%d", &u, &v); 73 Add(u, v); 74 Add(v, u); 75 deg[u]++; 76 deg[v]++; 77 } 78 bool done = false; 79 if (x >= y) 80 { 81 for (int i = 1; i <= n; i++) 82 { 83 if (deg[i] == n-1) 84 { 85 ans = y*(n-2)+x; 86 printf("%lld\n", ans); 87 done = true; 88 break; 89 } 90 } 91 if (done) continue; 92 ans = (n-1)*y; 93 printf("%lld\n", ans); 94 continue; 95 } 96 dfs(1, 0); ans = len*x + (n-1-len)*y; 97 printf("%lld\n", ans); 98 } 99 return 0; 100 }