AcWing237。プログラムの自動分析
アイデア
最初に等式をマージし、次に不等式が既知の条件と矛盾するかどうかを判断します
自動プログラム分析のプロセスでは、いくつかの制約を同時に満たすことができるかどうかを判断する必要があることがよくあります。
制約充足問題の単純化されたバージョンを考えてみましょう。x1 、x 2、x 3 x_ {1}、x_ {2}、x_ {3}と仮定します。バツ1、バツ2、バツ3、... xi = xj x_ {i} = x_ {j}の形式のnが与えられた場合に、プログラムに表示される変数を表します。バツ私=バツJまたはxi≠xjx_ {i}≠x_ {j}バツ私=バツJ変数の等しい/等しくない制約条件については、上記のすべての制約が同時に満たされるように、各変数に適切な値を割り当てることができるかどうかを判断してください。
たとえば、問題の制約は次のとおりです。x1 = x 2、x 2 = x 3、x 3 = x 4、x1≠x4 x_ {1} = x_ {2}、x_ {2} = x_ { 3}、x_ {3} = x_ {4}、x_ {1}≠x_ {4}バツ1=バツ2、x2=バツ3、x3=バツ4、x1=バツ4明らかに、これらの制約を同時に満たすことはできないため、この質問は満たされないものと判断する必要があります。
ここで、いくつかの制約充足問題を与えます。それらを別々に判断してください。
入力フォーマット
入力ファイルの最初の行には、決定する必要のある質問の数を表す正の整数tが含まれています。これらの質問は互いに独立していることに注意してください。
質問ごとに、いくつかの行を含めます。
最初の行には正の整数nが含まれています。これは、問題で満たす必要のある制約の数を表します。
次のn行、各行には3つの整数i、j、eが含まれ、隣接する整数間の単一のスペースで区切られた、等しい/等しくない制約条件を記述します。e = 1の場合、制約条件はxi = xj x_ {i} = x_ {j}です。バツ私=バツJ; e = 0の場合、制約条件はxi≠xj x_ {i}≠x_ {j}です。バツ私=バツJ。
出力フォーマット
出力ファイルにはt行が含まれます。
出力ファイルのk行目は、文字列「YES」または「NO」(引用符なし、すべて大文字)を出力します。「YES」は、入力のk番目の質問が満たされていると判断されることを意味し、「NO」は、満足できないこと満足。
データ範囲
1≤n≤10000001≤n≤1000000 1≤n≤1 0 0 0 0 0 0
1≤I、J≤10000000001≤i、j≤10000000001≤私、j≤1 0 0 0 0 0 0 0 0 0
コード
#include<iostream>
#include<cstdio>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<stack>
#include<algorithm>
#include<vector>
#include<utility>
#include<deque>
#include<unordered_map>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define endl '\n'
#define eps 1e-6
inline int gcd(int a, int b) {
return b ? gcd(b, a % b) : a; }
inline int lowbit(int x) {
return x & -x; }
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 2000010;
int f[N], n, m;
unordered_map<int, int>S;
struct Query {
int x, y, e;
}query[N];
int Find(int x) {
return x == f[x] ? x : f[x] = Find(f[x]);
}
int get(int x) {
if (S.count(x) == 0)S[x] = ++n;
return S[x];
}
int main() {
int t;cin >> t;
while (t--) {
S.clear();
n = 0;
scanf("%d", &m);
for (int i = 0; i < m;++i) {
int x, y, e;
scanf("%d%d%d", &x, &y, &e);
query[i] = {
get(x),get(y),e };
}
for(int i = 1; i <= n;++i)f[i] = i;
bool has = false;
for (int i = 0; i < m;++i) {
if (query[i].e == 1)f[Find(query[i].x)] = Find(query[i].y);
}
for (int i = 0;i < m;++i) {
if (query[i].e == 0 && Find(query[i].x) == Find(query[i].y)) {
has = true;
break;
}
}
if (has)puts("NO");
else puts("YES");
}
return 0;
}