zoukankan      html  css  js  c++  java
  • hdu 4115 (2—SAT)

    题意:两个人石头剪刀布,一个人的出法已确定,另一个人的出法有一定约束,某两次要相同或者不同,问你第二个人能否全部都不失败。

    思路:根据Bob出的情况,我们可以确定每次Alice有两种方案

    R与P,S矛盾,P与R,S矛盾,S与R,P矛盾。

    根据Bob出的情况建边:

    如果Bob出的是石头(R)则Alice可以出石头或者布,就是~R与~P矛盾,~P与~R矛盾,建边~R—>P,~P—>R。

    ........................................

    根据约束条件:

    如果a,b两轮是一样的就是Ra与~Rb矛盾,Rb与~Ra矛盾,建边Ra—>Rb,Rb—>Ra,

    ........................................

    如果a,b两轮不一样就是Ra与Rb矛盾,Rb与Ra矛盾,建边Ra—>~Rb,Rb—>~Ra,

    .......................................





    #include<stdio.h>
    #include<string.h>
    #include<stack>
    const int N=61000;
    using namespace std;
    int head[N],num,low[N],dfs[N],idx,ans,belong[N],ins[N];
    stack<int>Q;
    struct edge
    {
    	int st,ed,next;
    }e[N*10];
    void addedge(int x,int y)
    {
    	e[num].st=x;e[num].ed=y;e[num].next=head[x];head[x]=num++;
    }
    void Tarjan(int u)//缩点  
    {  
        int i,v;  
        Q.push(u);  
        ins[u]=1;  
        low[u]=dfs[u]=idx++;  
        for(i=head[u];i!=-1;i=e[i].next)  
        {  
            v=e[i].ed;  
            if(dfs[v]==-1)  
            {  
                Tarjan(v);  
                low[u]=low[u]>low[v]?low[v]:low[u];  
            }  
            else if(ins[v]==1)  
                low[u]=low[u]>dfs[v]?dfs[v]:low[u];  
        }  
        if(dfs[u]==low[u])  
        {  
            do  
            {  
                v=Q.top();  
                Q.pop();  
                ins[v]=0;//又忘了这个,调了半天  
                belong[v]=ans;
            }while(v!=u);  
            ans++;  
        }  
    }  
    int main()
    {
    	int i,x,y,a[3],b[3],c,t,op=1,k,n,m;
    	scanf("%d",&t);
    	while(t--)
    	{
    		memset(head,-1,sizeof(head));
    		num=0;
    		scanf("%d%d",&n,&m);
    		k=3*n;
    		for(i=1;i<=n;i++)
    		{
    			a[0]=i;a[1]=a[0]+n;a[2]=a[1]+n;
    			addedge(a[0],k+a[1]);addedge(a[0],k+a[2]);//R->非P,R->非S
    			addedge(a[1],k+a[0]);addedge(a[1],k+a[2]);//P->非R,P->非S
    			addedge(a[2],k+a[0]);addedge(a[2],k+a[1]);//S->非R,s->非R
    		}
    		for(i=1;i<=n;i++)
    		{
    			a[0]=i;a[1]=a[0]+n;a[2]=a[1]+n;
    			scanf("%d",&x);
    			if(x==3)//Bob出的是剪刀
    			{
    				addedge(k+a[0],a[2]);//非R->P
    				addedge(k+a[2],a[0]);//非P->R
    			}
    			else
    			{
    				addedge(k+a[x],a[x-1]);
    				addedge(k+a[x-1],a[x]);
    			}
    		}
    		for(i=0;i<m;i++)
    		{
    			scanf("%d%d%d",&x,&y,&c);
    			a[0]=x;a[1]=a[0]+n;a[2]=a[1]+n;
    			b[0]=y;b[1]=b[0]+n;b[2]=b[1]+n;
    			if(c==0)
    			{
    				addedge(a[0],b[0]);addedge(b[0],a[0]);
    				addedge(a[1],b[1]);addedge(b[1],a[1]);
    				addedge(a[2],b[2]);addedge(b[2],a[2]);
    				
    			}
    			else 
    			{
    				addedge(a[0],k+b[0]);addedge(b[0],k+a[0]);
    				addedge(a[1],k+b[1]);addedge(b[1],k+a[1]);
    				addedge(a[2],k+b[2]);addedge(b[2],k+a[2]);
    			}
    		}
    		memset(dfs,-1,sizeof(dfs));
    		idx=0,ans=0;
    		memset(belong,0,sizeof(belong));
    		memset(ins,0,sizeof(ins));
    		for(i=1;i<=k+k;i++)
    		{
    			if(dfs[i]==-1)
    				Tarjan(i);
    		}
    		for(i=1;i<=n;i++)
    		{
    			a[0]=i;a[1]=a[0]+n;a[2]=a[1]+n;
    			if(belong[a[0]]==belong[a[0]+k])break;
    			if(belong[a[1]]==belong[a[1]+k])break;
    			if(belong[a[2]]==belong[a[2]+k])break;
    		}
    		printf("Case #%d: ",op++);
    		if(i<=n)
    			printf("no
    ");
    		else printf("yes
    ");
    	}
    	return 0;
    }
    


  • 相关阅读:
    Beego 学习笔记12:文件的操作
    Beego 学习笔记11:文件的上传下载
    Beego 学习笔记10:Easyui使用
    Beego 学习笔记9:Boostrap使用介绍
    Beego 学习比较8:SQL语句
    Beego 学习笔记7:JS分页
    Beego学习笔记6:分页的实现
    【嵌入式linux】用户登录密码验证配置
    【Linux 环境搭建】ubuntu下nfs安装与配置
    【嵌入式 Linux文件系统】如何使用NFS文件系统
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3364610.html
Copyright © 2011-2022 走看看