hdu3446 daizhenyang's chess 【一般图匹配】
来源:互联网 发布:换字体软件 编辑:程序博客网 时间:2024/05/09 14:24
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3446
题意:在一个R行C列的棋盘上,俩个人轮流移动一个棋子,每次可以向相邻的20个格子移动,走过的每个格子自能走一次。另外,某些各自一开始就固定了不能走。 无法移动者输。问:先手能否赢。
分析:首先,忽略K点,将其他能相互移动的格子连边,求一次最大匹配,再将K点加入图中,若存在增广路,则先手赢,否则后手赢。
代码:
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 400#define Mm 20005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;struct edge { int v,next;}e[Mm];int tot,head[Mn];void addedge(int u,int v) { e[tot].v=v; e[tot].next=head[u]; head[u]=tot++;}int cnt,pre[Mn];int findpre(int x) { return x==pre[x]?pre[x]:pre[x]=findpre(pre[pre[x]]);}void ol(int a,int b) { a=findpre(a); b=findpre(b); if(a!=b) pre[a]=b;}int lk[Mn],vis[Mn],mark[Mn],match[Mn],ne[Mn];int lca(int x,int y) { static int t=0;t++; while(1) { if(x!=-1) { x=findpre(x); if(vis[x]==t) return x; vis[x]=t; if(match[x]!=-1) x=ne[match[x]]; else x=-1; } swap(x,y); }}queue<int> q;void group(int a,int p) { while(a!=p) { int b=match[a],c=ne[b]; if(findpre(c)!=p) ne[c]=b; if(mark[b]==2) mark[b]=1,q.push(b); if(mark[c]==2) mark[c]=1,q.push(c); ol(a,b),ol(b,c); a=c; }}void aug(int s) { for(int i=0;i<=cnt;i++) { ne[i]=-1; pre[i]=i; mark[i]=0; vis[i]=-1; } mark[s]=1; while(!q.empty()) q.pop(); q.push(s); while((!q.empty())&&match[s]==-1) { int u=q.front(); q.pop(); for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(match[u]==v||findpre(u)==findpre(v)||mark[v]==2) continue; if(mark[v]==1) { int r=lca(u,v); if(findpre(u)!=r) ne[u]=v; if(findpre(v)!=r) ne[v]=u; group(u,r); group(v,r); } else if(match[v]==-1) { ne[v]=u; for(int x=v;~x;) { int y=ne[x]; int mv=match[y]; match[x]=y,match[y]=x; x=mv; } break; } else { ne[v]=u; q.push(match[v]); mark[match[v]]=1; mark[v]=2; } } }}int mp[Mn][Mn],num[Mn][Mn];void init() { tot=0;cnt=0; CLR(mp,0); CLR(head,-1); CLR(num,0);}int way[20][2]={-2,-2,-2,-1,-2,1,-2,2,-1,-2,-1,-1,-1,0,-1,1,-1,2,0,-1,0,1,1,-2,1,-1,1,0,1,1,1,2,2,-2,2,-1,2,1,2,2};int main() { int t,n,m,kx,ky; char s[Mn]; scanf("%d",&t); for(int cas=1;cas<=t;cas++) { scanf("%d%d",&n,&m); init(); for(int i=0;i<n;i++) { scanf("%s",s); for(int j=0;j<m;j++) { if(s[j]=='K') { kx=i,ky=j; } if(s[j]!='#') { num[i][j]=++cnt; } } } for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(!num[i][j]||(i==kx&&j==ky)) continue; for(int k=0;k<20;k++) { int x=i+way[k][0]; int y=j+way[k][1]; if(x<0||x>=n||y<0||y>=m||(x==kx&&y==ky)||!num[x][y]) continue; int u=num[i][j],v=num[x][y]; if(!mp[u][v]) { addedge(u,v); addedge(v,u); mp[u][v]=mp[v][u]=1; } } } } for(int i=1;i<=cnt;i++) match[i]=-1; for(int i=1;i<=cnt;i++) { if(match[i]==-1) { aug(i); } } for(int k=0;k<20;k++) { int x=kx+way[k][0]; int y=ky+way[k][1]; if(x<0||x>=n||y<0||y>=m||!num[x][y]) continue; int u=num[kx][ky],v=num[x][y]; addedge(u,v); addedge(v,u); } aug(num[kx][ky]); printf("Case #%d: ",cas); if(match[num[kx][ky]]==-1) printf("daizhenyang lose\n"); else printf("daizhenyang win\n"); } return 0;}
0 0
- hdu3446 daizhenyang's chess,一般图匹配
- hdu3446 daizhenyang's chess 【一般图匹配】
- hdu3537 Daizhenyang's Coin
- HDOJ 3537 Daizhenyang's Coin
- HDU 3537 Daizhenyang's Coin
- 【hdu 3537】Daizhenyang's Coin
- 一般图匹配带花树
- HDU4687 (一般图匹配)
- 一般图匹配带花树
- 一般图最大匹配
- 一般图最大匹配
- HDU3551 一般图最大匹配
- 带花树 一般图最大匹配
- 一般图匹配带花树模板
- uva753(一般图匹配)
- 一般图匹配--带花树算法
- [UOJ79]一般图最大匹配
- 一般图匹配带花树模板
- SpringMVC 注解详解
- Spring中SimpleFromController
- Android使用addView动态添加组件
- freopen读入/写出 数据 从/到 文件
- Android中几种图像特效处理的集锦!!
- hdu3446 daizhenyang's chess 【一般图匹配】
- External file changes sync may be slow Native file wathcher is not executable
- cmd 笔记
- leetcode-329. Longest Increasing Path in a Matrix
- Java Web技术相关概念
- List list = new ArrayList();和ArrayList list=new ArrayList();的区别
- 可执行文件的装载于进程
- 并查集
- OpenCV实践之路——opencv与MFC强强联合打开图片