zoukankan      html  css  js  c++  java
  • poj--3678--Katu Puzzle(2-sat 建模)

    Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

    Status

    Description

    Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) such that for each edge e(a, b) labeled by op and c, the following formula holds:

     XaopXb = c

    The calculating rules are:

    AND 0 1
    0 0 0
    1 0 1
    OR 0 1
    0 0 1
    1 1 1
    XOR 0 1
    0 0 1
    1 1 0

    Given a Katu Puzzle, your task is to determine whether it is solvable.

    Input

    The first line contains two integers N (1 ≤ N ≤ 1000) and M,(0 ≤ M ≤ 1,000,000) indicating the number of vertices and edges.
    The following M lines contain three integers a (0 ≤ a < N), b(0 ≤ b < N), c and an operator op each, describing the edges.

    Output

    Output a line containing "YES" or "NO".

    Sample Input

    4 4
    0 1 1 AND
    1 2 1 OR
    3 2 0 AND
    3 0 0 XOR

    Sample Output

    YES

    Hint

    X0 = 1, X1 = 1, X2 = 0, X3 = 1.



    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define MAX 1000000+10
    int low[MAX],dfn[MAX];
    int sccno[MAX],m,n;
    int scc_cnt,dfs_clock;
    bool Instack[MAX];
    vector<int>G[MAX];
    stack<int>s;
    void init()
    {
    	for(int i=0;i<2*n;i++)
    	G[i].clear();
    }
    void getmap()
    {
    	while(m--)
    	{
    		int a,b,c;
    		char op[5];
    		memset(op,'',sizeof(op));
    		scanf("%d%d%d%s",&a,&b,&c,op);
    		if(op[0]=='A')
    		{
    			if(c==1)
    			{
    				G[a+n].push_back(a);
    				G[b+n].push_back(b);
    			}
    			else 
    			{
    				G[a].push_back(b+n);
    				G[b].push_back(a+n);
    			}
    		}
    		else if(op[0]=='O')
    		{
    			if(c==1)
    			{
    				G[a+n].push_back(b);
    				G[b+n].push_back(a);
    			}
    			else 
    			{
    				G[a].push_back(a+n);
    				G[b].push_back(b+n);
    			}
    		}
    		else if(op[0]=='X')
    		{
    			if(c==1)
    			{
    				G[a+n].push_back(b);
    				G[b+n].push_back(a);
    				G[a].push_back(b+n);
    				G[b].push_back(a+n);
    			}
    			else 
    			{
    				G[a].push_back(b);
    				G[b].push_back(a);
    				G[a+n].push_back(b+n);
    				G[b+n].push_back(a+n);
    			}
    		}
    	}
    }
    void tarjan(int u,int fa)
    {
    	int v;
    	low[u]=dfn[u]=++dfs_clock;
    	Instack[u]=true;
    	s.push(u);
    	for(int i=0;i<G[u].size();i++)
    	{
    		v=G[u][i];
    		if(!dfn[v])
    		{
    			tarjan(v,u);
    			low[u]=min(low[v],low[u]);
    		}
    		else if(Instack[v])
    		low[u]=min(low[u],dfn[v]);
    	}
    	if(low[u]==dfn[u])
    	{
    		++scc_cnt;
    		for(;;)
    		{
    			v=s.top();
    			s.pop();
    			Instack[v]=false;
    			sccno[v]=scc_cnt;
    			if(v==u) break;
    		}
    	}
    }
    void find(int l,int r)
    {
    	memset(low,0,sizeof(low));
    	memset(dfn,0,sizeof(dfn));
    	memset(sccno,0,sizeof(sccno));
    	memset(Instack,false,sizeof(Instack));
    	scc_cnt=dfs_clock=0;
    	for(int i=l;i<=r;i++)
    	if(!dfn[i]) tarjan(i,-1);
    }
    void solve()
    {
    	for(int i=0;i<n;i++)
    	{
    		if(sccno[i]==sccno[i+n])
    		{
    			printf("NO
    ");
    			return ;
    		}
    	}
    	printf("YES
    ");
    }
    int main()
    {
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		init();
    		getmap();
    		find(0,2*n-1);
    		solve();
    	}
    	return 0;
    }


  • 相关阅读:
    代码阅读:结构与逻辑
    ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上)
    大白话讲解Promise(一)
    ReactiveCocoa 中 RACSignal 是如何发送信号的
    The Future Of ReactiveCocoa by Justin Spahr-Summers
    reactive programming
    【转】iOS中流(Stream)的使用
    NSStream 流式思想
    Future模式 总结
    备忘
  • 原文地址:https://www.cnblogs.com/playboy307/p/5273750.html
Copyright © 2011-2022 走看看