NOI 2015 程序自动分析

来源:互联网 发布:人工智能这本书 编辑:程序博客网 时间:2024/04/25 01:30

Description

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

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

现在给出一些约束满足问题,请分别对它们进行判定。

Input

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

对于每个问题,包含若干行:

第 1 行包含 1个正整数 n,表示该问题中需要被满足的约束条件个数。

接下来 n行,每行包括 3 个整数 i,j,e,描述 1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若 e=1,则该约束条件为 xi=xj;若 e=0,则该约束条件为 xi≠xj。

Output

输出文件包括 t 行。

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

Sample Input

<1>

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

<2>

2
3
1 2 1
2 3 1
3 1 1
4
1 2 1
2 3 1
3 4 1
1 4 0

Sample Output

<1>

NO
YES

<2>

YES
NO

Hint

在第一个问题中,约束条件有三个:x1=x2,x2=x3,x3=x1。只需赋值使得 x1=x2=x3,即可同时满足所有的约束条件。

在第二个问题中,约束条件有四个:x1=x2,x2=x3,x3=x4,x1≠x4。由前三个约束条件可以推出 x1=x2=x3=x4,然而最后一个约束条件却要求 x1≠x4,因此不可被满足。

Source

NOI 2015 Day 1 T1

这里写图片描述

题解<1>

/*题目          提交者 结果      用时      内存      语言程序自动分析  saruka  100     512ms   10692kb     C++*/#include<cstdio>int getint(){    int r = 0, k = 1;    char c = getchar();    for(; c < '0' || c > '9'; c = getchar())        if(c == '-') k = -1;    for(; c >= '0' && c <= '9'; c = getchar())        r = r * 10 + c - '0';    return r * k;}const int maxn = 1000100;const int mod = 1000000;int n, T, x, y, e, cnt;int ueq[maxn][2], fa[2 * maxn];inline int hash(int x){    return x > mod ? (mod + x / mod + x % mod): x;}int getfather(int x){    return fa[x] = (fa[x] == x) ? x : getfather(fa[x]);}int main(){    T = getint();    while(T--)    {        cnt = 0;        n = getint();        for(int i = 1; i < 2 * maxn; i++) fa[i] = i;        for(int i = 1; i <= n; i++)        {            x = getint();            y = getint();            e = getint();            x = hash(x);            y = hash(y);             if(e == 1)            {                fa[getfather(x)] = getfather(y);            }            else             {                ++cnt;                ueq[cnt][0] = x;                ueq[cnt][1] = y;              }         }           bool flag = 1;        for(int i = 1; i <= cnt; i++)        {            if(getfather(ueq[i][0]) == getfather(ueq[i][1]))            {                flag = 0;                break;            }        }        printf(flag ? ("YES\n") : ("NO\n"));         }    return 0;}

题解<2>

/*题目          提交者 结果      用时      内存      语言程序自动分析  saruka  100     1183ms  9840kb      C++*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000010;inline int getint(){    int r = 0, k = 1;    char c = getchar();    for(; c < '0' || c > '9'; c = getchar())        if(c == '-') k = -1;    for(; c >= '0' && c <= '9'; c = getchar())        r = r * 10 + c - '0';    return r * k;}int n, sz, tp;int tmp[maxn << 1], Hash[maxn << 1], p[maxn << 1];struct Node{    int x, y;    bool tp;} s[maxn];int Find_Hash(int x){    int l = 1, r = tp, mid;    while(r - l > 1)    {        mid = (l + r) >> 1;        if(Hash[mid] > x) r = mid;        else if(Hash[mid] < x) l = mid;        else if(Hash[mid] == x) return mid;    }    if(Hash[l] == x) return l;    return r;}bool cmp(const Node &A, const Node &B){    return A.tp > B.tp;}inline int find(int x){    int r = x, pre;    while(p[r] != r) r = p[r];    while(x != r)    {        pre = p[x];        p[x] = r;        x = pre;    }    return r;}int main(){    int T = getint();    int fx, fy;    while(T--)    {        n = getint();        sz = 0;        for(int i = 1; i <= n; i++)        {            s[i].x = getint();            s[i].y = getint();            s[i].tp = getint();            tmp[++sz] = s[i].x;            tmp[++sz] = s[i].y;        }        sort(tmp + 1, tmp + sz + 1);        tp = 1;        Hash[tp] = tmp[1];        for(int i = 2; i <= sz; i++)        {            if(tmp[i] != tmp[i - 1])            {                Hash[++tp] = tmp[i];            }        }        sort(s + 1, s + n + 1, cmp);        for(int i = 1; i <= tp; i++) p[i] = i;        int rec = 0, fool = 0;        for(int i = 1; s[i].tp == 1 && i <= n; i++)        {            fx = find(Find_Hash(s[i].x));            fy = find(Find_Hash(s[i].y));            p[fx] = fy;            rec = i;        }        for(int i = rec + 1; i <= n; i++)        {            fx = find(Find_Hash(s[i].x));            fy = find(Find_Hash(s[i].y));            if(fx == fy)            {                fool = 1;                puts("NO\n");                break;            }        }        if(!fool) puts("YES\n");    }    return 0;}

Powered By Saruka
Copyright © 2016 All Rights Reserved.

0 0
原创粉丝点击