NOI 2015 程序自動分析 並查集+離散化

題目鏈接
鏈接2
題目大意

給定n個關係, a = b 和 a != b ,求這些關係中是否不存在矛盾
不存在: 輸出YES
存在:輸出NO

樣例

Sample Input
2
2
1 2 1
1 2 0
2
1 2 1
2 1 1
Sample Output
NO
YES

思路

  • 利用並查集維護a = b 的情況, 把相等的維護在同一個集合,如果再查詢不相等的關係,如果存在有他們在同一個集合,就輸出NO
  • 由於數據很大,我們用到離散化
  • 本題利用unordered_map進行離散化

代碼

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_map>
using namespace std;

typedef long long ll;

struct node{
	int a, b;
};

const int N = 2000010;
int f[N];
vector<node> tem;
unordered_map<ll, int> m;
int cnt;

int mapping(ll x)
{
	if(m.count(x)) return m[x];
	return m[x] = cnt++;
}

void init()
{
	for(int i = 0; i < N; i++)
		f[i] = i;
}

int find(int x)
{
	if(x == f[x])
		return x;
	return f[x] = find(f[x]);
}

void unite(int x, int y)
{
	x = find(x);
	y = find(y);
	if(x == y)
		return ;
	f[x] = y;
}
int main()
{
	int t;
	scanf("%d", &t);
	while(t--)
	{
		tem.clear();
		init();
		m.clear();
		cnt = 1;
		int n;
		scanf("%d", &n);
		bool flag = true;
		for(int i = 1; i <= n; i++)
		{
			ll aa, bb;
			int e;
			scanf("%lld%lld%d", &aa, &bb, &e);
			int a = mapping(aa);
			int b = mapping(bb);
			if(e == 1)
				unite(a, b);
			else
			{
				node t;
				t.a = a;
				t.b = b;
				tem.push_back(t);
			}
		}
		for(int i = 0; i < tem.size(); i++)
		{
			int a = tem[i].a;
			int b = tem[i].b;
			if(find(a) == find(b))
				flag = false;
		}
		if(flag)
			cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章