zoukankan      html  css  js  c++  java
  • [poj] 3678 Katu Puzzle

    原题

    这是一道简单的2-SAT!
    其实2-SAT的题只要想明白怎么连边就很简单了啊!
    这道题的连边思路还是很简单的啊~这里就不赘述了。
    而对于是否存在可行解,只要判断是否在同一个强连通分量里。

    #include<cstdio>
    #include<stack>
    #define N 1010
    using namespace std;
    int n,m,bel[2*N],sum,t,head[2*N],cnt=1,dfn[2*N],low[2*N];
    stack <int> stk;
    char s[5];
    bool instk[2*N],exi[2*N];
    struct hhh
    {
        int to,next;
    }edge[4*N*(N-1)];
    
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;
        if (j=='-') j=getchar(),fu=-1;
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
    
    void add(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void Tarjan(int x)
    {
        dfn[x]=low[x]=++t;
        stk.push(x);
        instk[x]=1;
        for (int i=head[x],v;i;i=edge[i].next)
        {
    	v=edge[i].to;
    	if (!dfn[v])
    	{
    	    Tarjan(v);
    	    low[x]=min(low[x],low[v]);
    	}
    	else if (instk[v]) low[x]=min(low[x],dfn[v]);
        }
        if (low[x]==dfn[x])
        {
    	sum++;
    	int t;
    	do
    	{
    	    t=stk.top();
    	    bel[t]=sum;
    	    stk.pop();
    	    instk[t]=0;
    	}while(t!=x);
        }
    }
    
    int main()
    {
        n=read();
        m=read();
        for (int i=1,a,b,c;i<=m;i++)
        {
    	a=read();
    	b=read();
    	exi[a]=1;
    	exi[b]=1;
    	c=read();
    	scanf("%s",s);
    	if (s[0]=='A')
    	{
    	    if (c==1)
    	    {
    		add(a,a+n);
    		add(b,b+n);
    //		add(a+n,b+n);
    //		add(b+n,a+n);
    	    }
    	    else
    	    {
    		add(a+n,b);
    		add(b+n,a);
    	    }
    	}
    	else if (s[0]=='O')
    	{
    	    if (c==1)
    	    {
    		add(a,b+n);
    		add(b,a+n);
    	    }
    	    else
    	    {
    		add(a+n,a);
    		add(b+n,b);
    //		add(a,b);
    //		add(b,a);
    	    }
    	}
    	else
    	{
    	    if (c==1)
    	    {
    		add(a,b+n);
    		add(b,a+n);
    		add(b+n,a);
    		add(a+n,b);
    	    }
    	    else
    	    {
    		add(a,b);
    		add(a+n,b+n);
    		add(b,a);
    		add(b+n,a+n);
    	    }
    	}
        }
        for (int i=0;i<2*n;i++)
        	if (!dfn[i]) Tarjan(i);
        for (int i=0;i<n;i++)
    	if (exi[i] && bel[i]==bel[i+n])
    	{
    	    printf("NO");
    	    return 0;
    	}
        printf("YES");
        return 0;
    }
    
    
  • 相关阅读:
    【转】busybox分析——arp设置ARP缓存表中的mac地址
    【转】OpenWRT开发自定义应用方法
    10大白帽黑客专用的 Linux 操作系统
    原始套接字
    正则表达式
    如何解决虚拟机中的ubuntu系统方向键与退格键不能正常使用的问题
    数组 slice方法和splice方法的区别
    数组去重等数组实例
    JS实现表单全选以及取消全选实例
    JS实现表格隔行变色
  • 原文地址:https://www.cnblogs.com/mrha/p/7856109.html
Copyright © 2011-2022 走看看