zoukankan      html  css  js  c++  java
  • [UOJ#127][BZOJ4195][NOI2015]程序自动分析

    [UOJ#127][BZOJ4195][NOI2015]程序自动分析

    试题描述

    在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。

    考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x1≠x4,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
    现在给出一些约束满足问题,请分别对它们进行判定。

    输入

    输入文件的第1行包含1个正整数t,表示需要判定的问题个数。注意这些问题之间是相互独立的。

    对于每个问题,包含若干行:
    第1行包含1个正整数n,表示该问题中需要被满足的约束条件个数。
    接下来n行,每行包括3个整数i,j,e,描述1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若e=1,则该约束条件为xi=xj;若e=0,则该约束条件为xi≠xj。

    输出

    输出文件包括t行。

    输出文件的第k行输出一个字符串“YES”或者“NO”(不包含引号,字母全部大写),“YES”表示输入中的第k个问题判定为可以被满足,“NO”表示不可被满足。

    输入示例

    2
    2
    1 2 1
    1 2 0
    2
    1 2 1
    2 1 1

    输出示例

    NO
    YES

    数据规模及约定

    1≤n≤1000000

    1≤i,j≤1000000000

    题解

    离散化后,用个并查集,对于相等的两个变量把它们放在同一个连通块里,然后判断所有不等的条件中的两个元素是否在同一个连通块,在就输出 NO,否则输出 YES。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
    	if(Head == Tail) {
    		int l = fread(buffer, 1, BufferSize, stdin);
    		Tail = (Head = buffer) + l;
    	}
    	return *Head++;
    }
    int read() {
    	int x = 0, f = 1; char c = Getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    	return x * f;
    }
    
    #define maxn 100010
    
    int fa[maxn<<1], cnt[2], num[maxn<<1], cntn;
    struct Que {
    	int x, y;
    	Que() {}
    	Que(int _, int __): x(_), y(__) {}
    } con[2][maxn];
    
    int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); }
    
    int main() {
    	int T = read();
    	while(T--) {
    		int n = read();
    		cnt[0] = cnt[1] = cntn = 0;
    		for(int i = 1; i <= n; i++) {
    			int x = read(), y = read(), tp = read();
    			num[++cntn] = x; num[++cntn] = y;
    			con[tp][++cnt[tp]] = Que(x, y);
    		}
    		sort(num + 1, num + cntn + 1);
    		cntn = unique(num + 1, num + cntn + 1) - num - 1;
    		for(int i = 1; i <= cntn; i++) fa[i] = i;
    		for(int tp = 0; tp < 2; tp++)
    			for(int i = 1; i <= cnt[tp]; i++)
    				con[tp][i].x = lower_bound(num + 1, num + cntn + 1, con[tp][i].x) - num,
    				con[tp][i].y = lower_bound(num + 1, num + cntn + 1, con[tp][i].y) - num;
    		for(int i = 1; i <= cnt[1]; i++) {
    			int u = findset(con[1][i].x), v = findset(con[1][i].y);
    			if(u != v) fa[v] = u;
    		}
    		bool ok = 1;
    		for(int i = 1; i <= cnt[0]; i++) {
    			int u = findset(con[0][i].x), v = findset(con[0][i].y);
    			if(u == v){ ok = 0; break; }
    		}
    		puts(ok ? "YES" : "NO");
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    装箱拆箱操作
    《设计原本》试读:什么是设计
    代码大全中英文要点
    JSON对象和字符串之间的相互转换
    《设计原本》试读:何为真实?设计的概念
    Facebook后台技术探秘 世界最大的PHP网站
    重构模式:用异步计算替代长计算
    生命不息编程不止 Facebook CEO还在写代码
    万能的js复制按钮
    《网站设计解构》试读:1.1 可重用策略
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/7073044.html
Copyright © 2011-2022 走看看