CodeForces 618D Hamiltonian Spanning Tree

題意:要把全部的節點都訪問一次,而且不能重複訪問,有兩種方式訪問,一種是根據樹上的路徑ios

走和當前節點鏈接的下一個節點cost x, 或者能夠不走樹上邊,直接跳到不與當前節點鏈接的節點,cost yspa

 

分析:code

別被樹嚇着!blog

必定會走n-1條路,那麼就是有一些走樹上的邊,有一些不走。rem

若是樹上的路徑cost更大(x >= y),那麼儘量的不走樹上的路徑,那麼根據嘗試能夠找到規律string

若是有一個節點是全部節點的父節點,也就是說這個節點的度爲n-1,那麼只會走一個x其餘都是yit

若是沒有這個節點,必定能夠所有走yio

 

另外一種狀況若是(x < y),那麼也就是說要儘量的多走樹上的邊,咱們知道一個節點只能訪問一次,也就是說class

一個節點最多隻能連兩條邊出去,而後dfs搜索,找到最多能夠走多少條,每一個節點的度數若是不被剪完就能夠繼續連,stream

剩下的只能走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 }
相關文章
相關標籤/搜索