hdu 4735Little Wish~ lyrical step~ 重复覆盖

题目链接

给出一棵树, 树上点的值为0或1, 可以交换树上两个点的权值, 给出一个距离m, 所有的0距离最近的1的距离不能超过m, 求最少的交换次数。

首先对于每一个点u,所有离u的距离不超过m的点v, 加一条边(u, v)。

然后dlx, 剪枝的函数是当前1的个数+还需要的1的个数不超过1的总数, 具体看代码。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define pb(x) push_back(x)
  4 #define ll long long
  5 #define mk(x, y) make_pair(x, y)
  6 #define lson l, m, rt<<1
  7 #define mem(a) memset(a, 0, sizeof(a))
  8 #define rson m+1, r, rt<<1|1
  9 #define mem1(a) memset(a, -1, sizeof(a))
 10 #define mem2(a) memset(a, 0x3f, sizeof(a))
 11 #define rep(i, a, n) for(int i = a; i<n; i++)
 12 #define ull unsigned long long
 13 typedef pair<int, int> pll;
 14 const double PI = acos(-1.0);
 15 const double eps = 1e-8;
 16 const int mod = 1e9+7;
 17 const int inf = 1061109567;
 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 19 const int maxn = 200;
 20 const int maxNode = 10000;
 21 int head[maxn], num;
 22 struct node
 23 {
 24     int to, nextt, c;
 25 }e[maxn];
 26 void addEdge(int u, int v, int c) {
 27     e[num].to = v;
 28     e[num].nextt = head[u];
 29     e[num].c = c;
 30     head[u] = num++;
 31 }
 32 struct DLX {
 33     int L[maxNode], R[maxNode], U[maxNode], D[maxNode], row[maxNode], col[maxNode];
 34     int S[maxn], H[maxn], deep, ans[maxn], sz, n, m, kind[maxn], boy_num;
 35     void remove(int c) {
 36         for(int i = D[c]; i!=c; i = D[i]) {
 37             L[R[i]] = L[i];
 38             R[L[i]] = R[i];
 39         }
 40     }
 41     void resume(int c) {
 42         for(int i = U[c]; i!=c; i = U[i]) {
 43             L[R[i]] = i;
 44             R[L[i]] = i;
 45         }
 46     }
 47     int h() {
 48         int cnt = 0;
 49         int vis[105];
 50         mem(vis);
 51         for(int i = R[0]; i!=0; i = R[i]) {
 52             if(!vis[i]) {
 53                 cnt++;
 54                 vis[i] = 1;
 55                 for(int j = D[i]; j!=i; j = D[j]) {
 56                     for(int k = R[j]; k!=j; k = R[k]) {
 57                         vis[col[k]] = 1;
 58                     }
 59                 }
 60             }
 61         }
 62         return cnt;
 63     }
 64     void dfs(int d, int cnt) {
 65         if(d+h()>boy_num||cnt>=deep)
 66             return ;
 67         if(R[0] == 0) {
 68             deep = min(deep, cnt);
 69             return ;
 70         }
 71         int c = R[0];
 72         for(int i = R[0]; i!=0; i = R[i])
 73             if(S[c]>S[i])
 74                 c = i;
 75         for(int i = D[c]; i!=c; i = D[i]) {
 76             remove(i);
 77             for(int j = R[i]; j!=i; j = R[j])
 78                 remove(j);
 79             dfs(d+1, cnt+(!kind[row[i]]));
 80             for(int j = L[i]; j!=i; j = L[j])
 81                 resume(j);
 82             resume(i);
 83         }
 84         return ;
 85     }
 86     void add(int r, int c) {
 87         sz++;
 88         row[sz] = r;
 89         col[sz] = c;
 90         S[c]++;
 91         U[sz] = U[c];
 92         D[sz] = c;
 93         D[U[c]] = sz;
 94         U[c] = sz;
 95         if(~H[r]) {
 96             R[sz] = H[r];
 97             L[sz] = L[H[r]];
 98             L[R[sz]] = sz;
 99             R[L[sz]] = sz;
100         } else {
101             H[r] = L[sz] = R[sz] = sz;
102         }
103     }
104     void init(){
105         mem1(H);
106         num = boy_num = 0;
107         mem1(head);
108         deep = inf;
109         for(int i = 0; i<=n; i++) {
110             R[i] = i+1;
111             L[i] = i-1;
112             U[i] = i;
113             D[i] = i;
114         }
115         mem(S);
116         R[n] = 0;
117         L[0] = n;
118         sz = n;
119     }
120     void dfs(int u, int root, int fa, int d) {
121         add(root, u);
122         for(int i = head[u]; ~i; i = e[i].nextt) {
123             int v = e[i].to, c = e[i].c;
124             if(v == fa)
125                 continue;
126             if(c+d<=m)
127                 dfs(v, root, u, d+c);
128         }
129     }
130     void solve() {
131         init();
132         int u, v, c;
133         for(int i = 1; i<=n; i++) {
134             scanf("%d", &kind[i]);
135             boy_num+=kind[i];
136         }
137         for(int i = 0; i<n-1; i++) {
138             scanf("%d%d%d", &u, &v, &c);
139             addEdge(u, v, c);
140             addEdge(v, u, c);
141         }
142         for(int i = 1; i<=n; i++) {
143             dfs(i, i, -1, 0);
144         }
145         dfs(0, 0);
146         if(deep == inf)
147             deep = -1;
148         cout<<deep<<endl;
149     }
150 }dlx;
151 int main()
152 {
153     int t;
154     cin>>t;
155     for(int i = 1; i<=t; i++) {
156         printf("Case #%d: ", i);
157         scanf("%d%d", &dlx.n, &dlx.m);
158         dlx.solve();
159     }
160     return 0;
161 }
原文地址:https://www.cnblogs.com/yohaha/p/5054487.html