HDU 3957 Street Fighter (search, DLX, repeated coverage + precise coverage)

Source: Internet
Author: User

A classic question that I saw a long time ago has never been done. Today I am going to practice it. Street Bully

 

For n <= 25 roles, each role has 1 or 2 versions (which can be understood as the normal version or the outbreak version), and each role version can be Ko by several people.

Ask how many roles can be selected at least (each role can only be selected once), so that everyone else can be Ko (including all versions ).

 

Typical DLX. The first column 'sigma mode [I] 'indicates that it is overwritten by the KO's version. The last n columns indicate the selected persons, which are precisely overwritten.

That is, if accurate coverage is satisfied, duplicate coverage is completed, and the selected rows are minimized.

It is said that this question can be converted to only one coverage, or DFS + pruning. This is the case first.

Added a lot of comments to facilitate later reading.

 

Note that when using dance, you must first Delete the duplicate overwrite and then delete the exact overwrite...

2515 Ms

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <queue>#include <map>using namespace std;#define MP make_pair#define ll long long#define inf 0x3f3f3f3f#define maxr 88#define maxn (maxr*maxr)struct DLX{int m;// amount of columnint m1,m2;// amount of repeat column and exact columnint L[maxn],R[maxn],U[maxn],D[maxn],cnt;int row[maxn],col[maxn];int N[maxr],use[maxr],head[maxr];void init(int _m){// may need modify this functionm = _m;memset(head,-1,sizeof(head));memset(N,0,sizeof(N));for(int i=0;i<=m;++i){L[i]=i-1,R[i]=i+1;U[i]=D[i]=i;row[i]=0,col[i]=i;}L[0]=m,R[m]=0;cnt=m;best = inf;}void exrm(int c){// remove of exact cover, privateL[R[c]]=L[c],R[L[c]]=R[c];for(int i=D[c];i!=c;i=D[i])for(int j=R[i];j!=i;j=R[j])U[D[j]]=U[j],D[U[j]]=D[j],--N[col[j]];}void exres(int c){// resume of exact cover, privatefor(int i=U[c];i!=c;i=U[i])for(int j=L[i];j!=i;j=L[j])U[D[j]]=D[U[j]]=j,++N[col[j]];L[R[c]]=R[L[c]]=c;}void rm(int x){// remove of repeat cover, privatefor(int i=D[x];i!=x;i=D[i])L[R[i]]=L[i],R[L[i]]=R[i];}void res(int x){// resume of repeat cover, privatefor(int i=D[x];i!=x;i=D[i])L[R[i]]=R[L[i]]=i;}int low(){// private, sometimes need modify this functionint mi=maxr,idx=0;for(int i=R[0];i<=m1;i=R[i])if(N[i]<mi&&N[i])mi=N[i],idx=i;return idx;}void link(int r,int c){++N[c],++cnt;row[cnt]=r,col[cnt]=c;U[cnt]=U[c],D[cnt]=c;U[D[cnt]]=D[U[cnt]]=cnt;if(head[r]==-1)head[r]=L[cnt]=R[cnt]=cnt;else {L[cnt]=L[head[r]];R[cnt]=head[r];L[R[cnt]]=R[L[cnt]]=cnt;}}bool del[maxr];int cost2(){// lower_boundint ret=0;memset(del,false,sizeof(del));for(int c=R[0];c && c<=m1;c=R[c]){if(!del[c]){del[c]=true;ret++;for(int i=D[c];i!=c;i=D[i])for(int j=R[i];j!=i;j=R[j])del[col[j]]=true;}}return ret;}int best;void dance(int dep,int val){// always need modify this functionif(R[0]==0 || R[0]>m1){best = min(best, val);return ;}int c=low();if(c==0)return ;if(dep+cost2()>=best) return ;for(int i=D[c];i!=c;i=D[i]){int r=row[i];use[dep]=i;rm(i);for(int j=R[i];j!=i;j=R[j]) if(col[j]<=m1) rm(j);for(int j=R[i];j!=i;j=R[j]) if(col[j]>m1) exrm(col[j]);dance(dep+1,val+1);for(int j=L[i];j!=i;j=L[j]) if(col[j]>m1) exres(col[j]);for(int j=L[i];j!=i;j=L[j]) if(col[j]<=m1) res(j);res(i);}}}dlx;int mode[30];int sum[30];vector<pair<int,int> >beat[30][2];int main(){int t,ca=0;scanf("%d",&t);while(t--){int n;scanf("%d",&n);for(int i=0;i<n;++i){scanf("%d",mode+i);if(i==0) sum[i] = mode[i];else sum[i] = sum[i-1]+mode[i];for(int j=0;j<mode[i];++j){int k,beatp,beatm;scanf("%d",&k);beat[i][j].clear();for(int kk=0;kk<k;++kk){scanf("%d%d",&beatp,&beatm);beat[i][j].push_back(MP(beatp,beatm));}}}dlx.init(sum[n-1]+n);dlx.m1 = sum[n-1], dlx.m2 = n;for(int i=0;i<n;++i){for(int j=0;j<mode[i];++j){int row = (i?sum[i-1]:0)+j+1;dlx.link(row,sum[n-1]+i+1);// exact coverdlx.link(row,(i?sum[i-1]:0)+1);// repeat coverif(mode[i]==2) dlx.link(row,(i?sum[i-1]:0)+2);// repeat coverfor(int k=0;k<beat[i][j].size();++k){// repeat coverpair<int,int>tmp = beat[i][j][k];int beatp = tmp.first;int beatm = tmp.second;int col = (beatp?sum[beatp-1]:0)+beatm+1;dlx.link(row,col);}}}dlx.dance(0,0);printf("Case %d: %d\n",++ca,dlx.best);}    return 0;}

 

HDU 3957 Street Fighter (search, DLX, repeated coverage + precise coverage)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.