zoukankan      html  css  js  c++  java
  • 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
    ",++cas,an==INT_MAX?-1:an);
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    win7下的vxworks总结
    ubuntu 无法获得锁 /var/lib/dpkg/lock
    项目中用到了的一些批处理文件
    win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM
    使用opencv统计视频库的总时长
    January 05th, 2018 Week 01st Friday
    January 04th, 2018 Week 01st Thursday
    January 03rd, 2018 Week 01st Wednesday
    January 02nd, 2018 Week 01st Tuesday
    January 01st, 2018 Week 01st Monday
  • 原文地址:https://www.cnblogs.com/bin-gege/p/6360510.html
Copyright © 2011-2022 走看看