【DLX】 hdu3957 Street Fighter
来源:互联网 发布:人类迁徙 知乎 编辑:程序博客网 时间:2024/06/09 18:28
Street Fighter
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3957
题意:模拟街头霸王游戏(我都没玩过T-T),有N(2<=N<=25)个角色,每个人都有M(1<=M<=2)个模式,同时告诉你每个角色在某个模式可以击败其他的在某个模式的某个角色,问你最少选择几个角色可以击败其他所有角色,无论其他角色在什么模式下。
题解:DLX的重复覆盖问题,但是要考虑一个角色有多个模式,而且每个角色只能选择一次。
1)同时使用重复覆盖和精确覆盖。
2)只用重复覆盖,同时使用一个数组记录使用了什么角色。
代码是实现第二种。
代码:
#include<cstdio>#include<cstring>#include<climits>#define N 55#define M 2525using namespace std;struct{ int col,row;} node[M];int l[M],r[M],d[M],u[M],h[M],res[N],cntcol[N];int dcnt=-1,minn;int n,m;bool visit[N];//标记使用哪个角色的哪个模式int H()//a*加速{ int count=0; bool hash[N]; memset(hash,false,sizeof(hash)); for(int i=r[0]; i!=0; i=r[i]) { if(hash[i]) continue; hash[i]=true; count++; for(int j=d[i]; j!=i; j=d[j]) for(int k=r[j]; k!=j; k=r[k]) hash[node[k].col]=true; } return count;}void addnode(int &x){ ++x; r[x]=l[x]=u[x]=d[x]=x;}void insert_row(int rowx,int x){ r[l[rowx]]=x; l[x]=l[rowx]; r[x]=rowx; l[rowx]=x;}void insert_col(int colx,int x){ d[u[colx]]=x; u[x]=u[colx]; d[x]=colx; u[colx]=x;}void dlx_init(int cols){ memset(h,-1,sizeof(h)); memset(cntcol,0,sizeof(cntcol)); dcnt=-1; addnode(dcnt); for(int i=1; i<=cols; ++i) { addnode(dcnt); insert_row(0,dcnt); }}void insert_node(int x,int y){ cntcol[y]++; addnode(dcnt); node[dcnt].row=x; node[dcnt].col=y; insert_col(y,dcnt); if(h[x]==-1) h[x]=dcnt; else insert_row(h[x],dcnt);}void remove(int c){ for(int i=d[c]; i!=c; i=d[i]) { l[r[i]]=l[i]; r[l[i]]=r[i]; }}void resume(int c){ for(int i=u[c]; i!=c; i=u[i]) { l[r[i]]=i; r[l[i]]=i; }}void DLX(int deep){ if(deep+H()>=minn) return; if(r[0]==0) { if(minn>deep) minn=deep; return; } int min=INT_MAX,tempc; for(int i=r[0]; i!=0; i=r[i]) if(cntcol[i]<min) { min=cntcol[i]; tempc=i; } for(int i=d[tempc]; i!=tempc; i=d[i]) { if(visit[node[i].row]) continue; res[deep]=node[i].row;//选择某个角色的某个模式 remove(i); for(int j=r[i]; j!=i; j=r[j]) remove(j); visit[node[i].row]=true; if(m==2) { if((node[i].row%2)&1) visit[node[i].row+1]=true; else visit[node[i].row-1]=true; } DLX(deep+1); visit[node[i].row]=false; if(m==2) { if((node[i].row%2)&1) visit[node[i].row+1]=false; else visit[node[i].row-1]=false; } for(int j=l[i]; j!=i; j=l[j]) resume(j); resume(i); } return;}int main(){ int k,T; int a,b; scanf("%d",&T); for(int cas=1; cas<=T; ++cas) { minn=INT_MAX; memset(visit,false,sizeof(visit)); scanf("%d",&n); scanf("%d",&m); dlx_init(n*m); //选择一个角色可以覆盖他所有的模式 for(int i=0; i<n; ++i) for(int j=0; j<m; ++j) for(int k=0; k<m; ++k) insert_node(i*m+j+1,i*m+k+1); for(int i=0; i<m; ++i) { scanf("%d",&k); for(; k--;) { scanf("%d%d",&a,&b); insert_node(i+1,a*m+b+1); } } for(int i=1; i<n; ++i) { scanf("%d",&m); for(int j=0; j<m; ++j) { scanf("%d",&k); for(; k--;) { scanf("%d%d",&a,&b); insert_node(i*m+j+1,a*m+b+1); } } } DLX(0); printf("Case %d: %d\n",cas,minn); } return 0;}
来源:http://blog.csdn.net/ACM_Ted
- 【DLX】 hdu3957 Street Fighter
- HDU3957-Street Fighter
- HDU 3957 Street Fighter(DLX搜索)
- [DLX重复覆盖] hdu 3957 Street Fighter
- Street Fighter hdoj3927
- HDU 3957 Street Fighter
- hdu3957Street Fighter(DLX重复覆盖)
- DLX hdu3111 hdu 3909 hdu3663 hdu3957
- HDU--3957[Street Fighter] 最小支配集
- hdu 3957 Street Fighter 重复覆盖于+精确覆盖 DancingLink
- Street
- DLX
- DLX
- DLX
- HDU3957 Dancing Links
- [英文歌曲]斗士:Fighter
- Street Numbers
- Street Race
- 免费素材:超棒的PSD格式UI套件 - Soft UI KIT
- 过去的不再重来,又何必去苦想?
- 博奕笔记
- 【hdu】 TOYS 几何
- VC6.0 “add files to project”功能失效的解决方案
- 【DLX】 hdu3957 Street Fighter
- Remmarguts' Date----POJ_2449----第k最短路
- dataGridView 的columnType设为DataGridViewCheckBoxColumn,当选择其他列进行排序时,DataGridViewCheckBoxColumn列值被还原
- 三(上)error
- 【简报】使用3D过渡效果的图片幻灯:Adaptor
- sqlserver触发器
- 流媒体的理论总结
- English Self-Introduction
- Log4Net使用指南