首页 > 代码库 > FZU 2165 v11(最小重复覆盖)

FZU 2165 v11(最小重复覆盖)

告诉你若干个(<=100)武器的花费以及武器能消灭的怪物编号,问消灭所有怪物(<=100)的最小花费。。。当然每个武器可以无限次使用,不然这题就太水了╮(╯▽╰)╭

 

这题当时比赛的时候连题都还没看就结束了。。。。赛后一看,果断是重复覆盖。。。

不过之后一直没敲。。。然后今天算是补回来吧,同时也把好久以前学的DLX复习一下。。。

DLX的话,双向十字链表。。。具体的话,百度Google什么的dancing links。。。

 

一开始敲的时候还是挺顺利的,因为之前做过几次重复覆盖都是直接拿精确覆盖的模板来改。。。差不多的,不过重复覆盖就删列,代码好像还少几行呢。。。不过有时调一会有时wa上一两发。。。又鉴于最近好像好多重复覆盖的题。。。就好像spfa一样频繁出现=。=个人感觉不科学。。。

而且之前那个精确覆盖的模板实在是无法直视,太挫了写得╮(╯▽╰)╭

重点来了~~~代码写好了,可是不AC╮(╯▽╰)╭太可恶了。。。。让JM帮忙看代码。。。于是苦逼地一直找bug。。。。

经过一小时吧大概的奋斗。。。JM发现。。。一个非常好笑的呵呵的亮点。。。。memset(vis,false,sizeof(false));。。。笑死我了。。。还好这是平时随便敲。。。

然后就AC了~~~

复杂度。。不知道怎么算DLX的复杂度哎~~~求高手教,或者说一般N,M多少可以~~

 

总结就是,打代码要仔细。。。。总之不要犯这种逗比错误。。。。真正比赛的时候就笑不出来了~~~啦啦啦~~~谢谢JM~~~

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <string>
  7 #include <vector>
  8 #include <queue>
  9 #include <set>
 10 using namespace std;
 11 
 12 #define ll long long
 13 #define eps 1e-8
 14 #define mod 21092013
 15 
 16 #define inf 0x3f3f3f3f
 17 #define maxr 110
 18 #define maxn (maxr*maxr)
 19 int n,m;
 20 int L[maxn],R[maxn],U[maxn],D[maxn],cnt;
 21 int row[maxn],col[maxn];
 22 int N[maxr],use[maxr],head[maxr];
 23 void init(){
 24     memset(head,-1,sizeof(head));
 25     memset(N,0,sizeof(N));
 26     for(int i=0;i<=m;++i){
 27         L[i]=i-1,R[i]=i+1;
 28         U[i]=D[i]=i;
 29         row[i]=0,col[i]=i;
 30     }
 31     L[0]=m,R[m]=0;
 32     cnt=m;
 33 }
 34 void remove(int x){// 删除列
 35     for(int i=D[x];i!=x;i=D[i])
 36         L[R[i]]=L[i],R[L[i]]=R[i];
 37 }
 38 void resume(int x){// 恢复列
 39     for(int i=D[x];i!=x;i=D[i])
 40         L[R[i]]=R[L[i]]=i;
 41 }
 42 int low(){
 43     int mi=maxr,idx=0;
 44     for(int i=R[0];i;i=R[i])if(N[i]<mi)mi=N[i],idx=i;
 45     return idx;
 46 }
 47 void link(int r,int c){
 48     ++N[c],++cnt;
 49     row[cnt]=r,col[cnt]=c;
 50     U[cnt]=U[c],D[cnt]=c;
 51     U[D[cnt]]=D[U[cnt]]=cnt;
 52     if(head[r]==-1)
 53         head[r]=L[cnt]=R[cnt]=cnt;
 54     else {
 55         L[cnt]=L[head[r]];
 56         R[cnt]=head[r];
 57         L[R[cnt]]=R[L[cnt]]=cnt;
 58     }
 59 }
 60 int cost[maxr];
 61 int ans;
 62 void dance(int dep,int val){
 63     if(R[0]==0){
 64         ans = min(ans,val);
 65         return ;
 66     }
 67     int c=low();
 68     if(c==0||val>=ans)return ;
 69     for(int i=D[c];i!=c;i=D[i]){
 70         use[dep]=i;
 71         remove(i);
 72         for(int j=R[i];j!=i;j=R[j])remove(j);
 73         dance(dep+1,val+cost[row[i]]);
 74         for(int j=L[i];j!=i;j=L[j])resume(j);
 75         resume(i);
 76     }
 77 }
 78 
 79 int main(){
 80     while(~scanf("%d%d",&m,&n)){
 81         init();
 82         bool vis[maxr];
 83         memset(vis,false,sizeof(vis));
 84         ans=0;
 85         for(int i=1;i<=n;++i){
 86             int tmp,tmp2;
 87             scanf("%d%d",cost+i,&tmp);
 88             ans+=cost[i];
 89             for(int j=0;j<tmp;++j){
 90                 scanf("%d",&tmp2);
 91                 vis[tmp2]=true;
 92                 link(i,tmp2);
 93             }
 94         }
 95         for(int i=1;i<=m;++i)if(vis[i]==false){vis[1]=false;break;}
 96         if(vis[1]==false){puts("-1");continue;}
 97         dance(0,0);
 98         printf("%d\n",ans);
 99     }
100     return 0;
101 }
View Code