zoukankan      html  css  js  c++  java
  • 【ZOJ3316】Game(带花树)

    【ZOJ3316】Game(带花树)

    题面

    Vjudge
    翻译:
    给定棋盘上(n)个旗子
    一开始先手可以随便拿,
    然后每次都不能取离上次的曼哈顿距离超过(L)的旗子
    谁不能动谁输。
    问后手能否赢?

    题解

    假的博弈论

    对于所有曼哈顿距离小于等于(L)的点连边
    检查是否存在完美匹配
    如果存在完美匹配,每次先手选择一个点,后手只需要选择对应的点即可。
    否则一定存在一个无法匹配的点,与它曼哈顿距离小于等于(L)的个数一定是偶数个(如果是奇数个就会与它匹配)
    那么这个联通块的大小是奇数个,后手必败。(假的证明)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 362
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next;}e[MAX*MAX];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    int dfn[MAX],tim;
    int f[MAX],n;
    int pre[MAX],vis[MAX],match[MAX];
    int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
    int lca(int u,int v)
    {
    	++tim;u=getf(u),v=getf(v);
    	while(dfn[u]!=tim)
    	{
    		dfn[u]=tim;
    		u=getf(pre[match[u]]);
    		if(v)swap(u,v);
    	}
    	return u;
    }
    queue<int> Q;
    void blossom(int x,int y,int w)
    {
    	while(getf(x)!=w)
    	{
    		pre[x]=y;y=match[x];
    		if(vis[y]==2)vis[y]=1,Q.push(y);
    		if(f[x]==x)f[x]=w;
    		if(f[y]==y)f[y]=w;
    		x=pre[y];
    	}
    }
    bool Aug(int S)
    {
    	for(int i=1;i<=n;++i)f[i]=i,vis[i]=pre[i]=0;
    	while(!Q.empty())Q.pop();Q.push(S);vis[S]=1;
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v;
    			if(getf(u)==getf(v)||vis[v]==2)continue;
    			if(!vis[v])
    			{
    				vis[v]=2;pre[v]=u;
    				if(!match[v])
    				{
    					for(int x=v,lst;x;x=lst)
    						lst=match[pre[x]],match[x]=pre[x],match[pre[x]]=x;
    					return true;
    				}
    				vis[match[v]]=1;Q.push(match[v]);
    			}
    			else
    			{
    				int w=lca(u,v);
    				blossom(u,v,w);blossom(v,u,w);
    			}
    		}
    	}
    	return false;
    }
    void init()
    {
    	memset(h,0,sizeof(h));cnt=1;
    	memset(match,0,sizeof(match));
    }
    int X[MAX],Y[MAX],L;
    int main()
    {
    	while(scanf("%d",&n)!=EOF)
    	{
    		init();
    		for(int i=1;i<=n;++i)X[i]=read(),Y[i]=read();
    		L=read();int ans=0;
    		if(n&1){puts("NO");continue;}
    		for(int i=1;i<=n;++i)
    			for(int j=i+1;j<=n;++j)
    				if(abs(X[i]-X[j])+abs(Y[i]-Y[j])<=L)
    					Add(i,j),Add(j,i);
    		for(int i=1;i<=n;++i)if(!match[i])ans+=Aug(i);
    		(ans==n/2)?puts("YES"):puts("NO");
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    安装nodejs和yarn(配置淘宝源)
    适用于 Linux 的 Windows 子系统没有已安装的分发版
    selenium定位元素click时报错
    dubbo从入门到实战(转)
    SpringBoot整合JPA简单介绍
    办公自动化路上的异化
    邮箱黑名单:如何查看邮件IP是否被列入黑名单,及如何删除
    邮箱黑名单(1):
    Vmware挂载san存储_vSphere 6.x 共享存储LUN丢失分区表修复(精华)
    AD中FSMO五大角色的介绍及操作
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8719571.html
Copyright © 2011-2022 走看看