hdu 4735 Little Wish~ lyrical step~(DLX)

题目链接:hdu 4735 Little Wish~ lyrical step~

题意:

有n个节点的树,每个节点可能是男孩,可能是女孩,节点之间有距离,现在要让所有的女孩周围距离D之内有男孩,问最小需要交换多少次男孩和女孩的位置。

题解:

把每个节点对小于D距离的全部link起来,然后DLX爆艹,意义就是选n个节点去覆盖全部节点,如果这个节点是女生,那么就是要替换的点。然后不断更新答案。

  1 #include<bits/stdc++.h>
  2 #define F(i,a,b) for(int i=a;i<=b;++i)
  3 using namespace std;
  4
  5 int boys,a[110],an;
  6
  7 struct DLX{
  8     const static int mn=1000;
  9     #define FF(i,A,s) for(int i=A[s];i!=s;i=A[i])
 10     #define INF 0x3f3f3f3f
 11     int L[mn],R[mn],U[mn],D[mn];
 12     int size,col[mn],row[mn],s[mn],H[mn];
 13     bool vis[70];
 14     int ans[mn],cnt;
 15     void init(int m){
 16         F(i,0,m)L[i]=i-1,R[i]=i+1,U[i]=D[i]=i,s[i]=0;
 17         memset(H,-1,sizeof(H));
 18         L[0]=m;R[m]=0;size=m+1;
 19     }
 20     void link(int r,int c){
 21          U[size]=c;D[size]=D[c];U[D[c]]=size;D[c]=size;
 22          if(H[r]<0)H[r]=L[size]=R[size]=size;
 23          else L[size]=H[r],R[size]=R[H[r]],L[R[H[r]]]=size,R[H[r]]=size;
 24          s[c]++,col[size]=c,row[size]=r,size++;
 25      }
 26     void del(int c){
 27         L[R[c]]=L[c];R[L[c]]=R[c];
 28         FF(i,D,c)FF(j,R,i)U[D[j]]=U[j],D[U[j]]=D[j],--s[col[j]];
 29     }
 30     void add(int c){
 31         R[L[c]]=L[R[c]]=c;
 32         FF(i,U,c)FF(j,L,i)++s[col[U[D[j]]=D[U[j]]=j]];
 33     }
 34     bool dfs(int k){//精确覆盖
 35         if(!R[0]){
 36             cnt=k;return 1;
 37         }
 38         int c=R[0];FF(i,R,0)if(s[c]>s[i])c=i;
 39         del(c);
 40         FF(i,D,c){
 41             FF(j,R,i)del(col[j]);
 42             ans[k]=row[i];if(dfs(k+1))return 1;
 43             FF(j,L,i)add(col[j]);
 44         }
 45         add(c);
 46         return 0;
 47     }
 48     void remove(int c){FF(i,D,c)L[R[i]]=L[i],R[L[i]]=R[i];}//重复覆盖
 49     void resume(int c){FF(i,U,c)L[R[i]]=R[L[i]]=i;}
 50     int A(){//估价函数
 51         int res=0;
 52         memset(vis,0,sizeof(vis));
 53         FF(i,R,0)if(!vis[i]){
 54                 res++;vis[i]=1;
 55                 FF(j,D,i)FF(k,R,j)vis[col[k]]=1;
 56             }
 57         return res;
 58     }
 59     void dfs(int now,int cnt){//重复覆盖
 60         if(now+A()>boys||cnt>=an)return;
 61         if(!R[0])
 62         {
 63             an=cnt;
 64             return;
 65         }
 66         int temp=INF,c;
 67         FF(i,R,0)if(temp>s[i])temp=s[i],c=i;
 68         FF(i,D,c){
 69             ans[now]=row[i];
 70             remove(i);FF(j,R,i)remove(j);
 71             dfs(now+1,cnt+!a[row[i]]);
 72             FF(j,L,i)resume(j);resume(i);
 73         }
 74     }
 75 }dlx;
 76
 77 int t,n,d,cas;
 78
 79 int g[60],v[110],w[110],nxt[110],ed;
 80
 81 void adg(int x,int y,int z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],g[x]=ed;}
 82
 83 void dfs(int x,int rt,int fa=0,int dis=0)
 84 {
 85     dlx.link(rt,x);
 86     for(int i=g[x];i;i=nxt[i])
 87         if(v[i]!=fa&&dis+w[i]<=d)
 88             dfs(v[i],rt,x,dis+w[i]);
 89 }
 90
 91 int main()
 92 {
 93     scanf("%d",&t);
 94     while(t--)
 95     {
 96         scanf("%d%d",&n,&d);
 97         boys=ed=0,dlx.init(n);
 98         memset(g,0,sizeof(g));
 99         F(i,1,n)scanf("%d",a+i),boys+=a[i];
100         F(i,1,n-1)
101         {
102             int x,y,z;
103             scanf("%d%d%d",&x,&y,&z);
104             adg(x,y,z);
105             adg(y,x,z);
106         }
107         F(i,1,n)dfs(i,i);
108         an=INT_MAX;
109         dlx.dfs(0,0);
110         printf("Case #%d: %d\n",++cas,an==INT_MAX?-1:an);
111     }
112     return 0;
113 }

时间: 2024-12-24 05:42:01

hdu 4735 Little Wish~ lyrical step~(DLX)的相关文章

HDU 4735 Little Wish~ lyrical step~(DLX , 重复覆盖)

解题思路: DLX 的模板题,重复覆盖. #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math

[DLX重复覆盖] hdu 4735 Little Wish~ lyrical step~

题意: 在一棵树上有n个节点,n-1条边,每条边有距离. 每个节点会给你原来是男孩还是女孩. 问最少要交换多少次,使得每个女孩都能被保护到. 保护到的条件是女孩和最近的男孩的距离小于等于D 思路: 首先要求一下mp[i][j],就是任意两个点之间的距离 这个方法随意都可以的. 因为男孩只能放在树上,所以行为树,列也为树 这样每次求出的cnt就是每次最多要有多少个男的在指定的树上 这时候就需要剪枝了 剪枝就是 1.如果x+h()>boy 需要男生数超过总的男生数 return 2.每次遍历一遍当前

HDU 4735 DLX爆搜

Little Wish~ lyrical step~ Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 417    Accepted Submission(s): 109 Problem Description N children are living in a tree with exactly N nodes, on each n

hdu - 3498 - whosyourdaddy(反复覆盖DLX)

题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉.问最少删几次能够删掉全部点. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498 -->>N个点看成 N 个要被覆盖的列,每一个点作为一行,与其相邻的点的位置在这一行中标为 1,还有它自已的位置也标记为 1.. 这就是经典的反复覆盖问题了..于是,DLX上场.. #include <cstdio> #include &l

hdu - 3498 - whosyourdaddy(重复覆盖DLX)

题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有点. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498 -->>N个点看成 N 个要被覆盖的列,每个点作为一行,与其相邻的点的位置在这一行中标为 1,还有它自已的位置也标记为 1.. 这就是经典的重复覆盖问题了..于是,DLX上场.. #include <cstdio> #include <

(中等) HDU 4979 A simple math problem. , DLX+重复覆盖+打表。

Description Dragon loves lottery, he will try his luck every week. One day, the lottery company brings out a new form of lottery called accumulated lottery. In a normal lottery, you pick 7 numbers from N numbers. You will get reward according to how

Dancing Links [Kuangbin带你飞] 模版及题解

学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/7627862 2份模版 第一份精确覆盖 from POJ 3074 const int N = 9; const int MAXN = N * N * N + 10; const int MAXM = N * N * 4 + 10; const int MAXNODE = MAXN * 4 + MAXM +

hdu 2295 Radar(二分+DLX)

题目链接:hdu 2295 Radar 题意: 给你n个城市,m个雷达,现在最多用K个雷达,求最小半径覆盖全部的城市. 题解: 二分半径套一个DLX就行.网上随便找的一个板子 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 const double eps=1e-7; 5 6 struct Point{ 7 double x,y; 8 }city[100

(hdu step 1.3.8)Who&#39;s in the Middle(排序)

题目: Who's in the Middle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2938 Accepted Submission(s): 1109   Problem Description FJ is surveying his herd to find the most average cow. He wants to k