zoukankan      html  css  js  c++  java
  • poj3678 Katu Puzzle

    题目链接

    题意

    给定一张图,对于每条边给出一个运算符((&,|,otimes))和一个值(c(0 le c le 1))。问能否通过给每个点赋上一个值。使得每条边通过指定的运算都能得到指定的值。

    思路

    (2-sat)问题,需要注意的是当两数(&)起来为(1)时。必须全部为(1),所以就从每个点的(0)(1)连边。同理,当两数(|)起来为(0)时,必须全部为(0),所以就从每个点的(1)(0)连边。

    代码

    /*
    * @Author: wxyww
    * @Date:   2019-04-27 16:42:24
    * @Last Modified time: 2019-04-27 17:09:58
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int N = 3000 + 10,M = 5000000 + 100;
    ll read() {
    	ll x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9') {
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9') {
    		x=x*10+c-'0';
    		c=getchar();
    	}
    	return x*f;
    }
    struct node {
    	int v,nxt;
    }e[M];
    int head[N],ejs;
    void add(int u,int v) {
    	e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;
    }
    char s[5];
    int sta[N],dfn[N],top,coljs,cnt,vis[N],low[N],col[N];
    void tarjan(int u) {
    	dfn[u] = low[u] = ++cnt;
    	sta[++top] = u;
    	vis[u] = 1;
    	for(int i = head[u];i;i = e[i].nxt) {
    		int v = e[i].v;
    		if(!dfn[v]) {
    			tarjan(v);
    			low[u] = min(low[u],low[v]);
    		}
    		else if(vis[v]) low[u] = min(low[u],low[v]);
    	}
    	if(low[u] == dfn[u]) {
    		++coljs;
    		do {
    			int x = sta[top--];
    			col[x] = coljs;
    			vis[x] = 0;
    		}while(sta[top + 1] != u);
    	}
    }
    int main() {
    	int n = read(),m = read();
    	for(int i = 1;i <= m;++i) {
    		int u = read() + 1,v = read() + 1,w = read();
    		scanf("%s",s + 1);
    		if(s[1] == 'O') {
    			if(w)	add(u,v + n),add(v,u + n);
    			else  add(u + n,u),add(v + n,v);
    		}
    		else if(s[1] == 'X') {
    			if(w) add(u,v + n),add(u + n,v),add(v + n,u),add(v,u + n);
    			else add(u,v),add(u + n,v + n),add(v,u),add(v + n,u + n);
    		}
    		else {
    			if(w) add(u,u + n),add(v,v + n);
    			else add(u + n,v),add(v + n,u);
    		}
    	}
    	for(int i = 1;i <= n + n;++i) if(!dfn[i]) tarjan(i);
    	for(int i = 1;i <= n;++i) {
    		if(col[i] == col[i + n]) {
    			puts("NO");return 0;
    		}
    	}
    	puts("YES");
    	return 0;
    }
    
  • 相关阅读:
    view间传值的方法总结
    初学者关于内存的思考(不断加深不断更新中)
    UITableView刷新数据reLoadData
    rsync安装指南
    Makefile完全解析PART5.使用变量
    Makefile完全解析PART10.使用make更新函数库文件
    windows linux 文件同步 cwrsync工具
    Makefile完全解析PART4.书写命令
    Makefile完全解析PART7.使用函数
    RSYNC安装使用详解
  • 原文地址:https://www.cnblogs.com/wxyww/p/poj3678.html
Copyright © 2011-2022 走看看