1. 程式人生 > >並查集:POJ 1182 食物鏈 復習

並查集:POJ 1182 食物鏈 復習

iostream unit color clu string using pan n) else

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;

const int maxn = 100000*3 + 100;
int par[maxn];
int Rank[maxn];
int N, K;
int T[maxn], X[maxn], Y[maxn];

//初始化n個元素 
void init(int n)
{
    for
(int i = 0; i < n; i++) { par[i] = i; Rank[i] = 0; } } //查詢樹的根 int Find(int x) { if (par[x] == x) { return x; } else { return par[x] = Find(par[x]); } } //合並x和y所述的集合 void unite(int x, int y) { x = Find(x); y
= Find(y); if (x == y) return; if (Rank[x] < Rank[y]) { par[x] = y; } else { par[y] = x; if (Rank[x] == Rank[y]) Rank[x]++; } } bool same(int x, int y) { return Find(x) == Find(y); } void input() { scanf("%d%d", &N, &K);
for (int i = 0; i < K; i++) { scanf("%d%d%d", &T[i], &X[i], &Y[i]); } } void solve() { input(); //初始化並查集 //元素x, x + N, x + 2*N 分別代表 x-A, y-B, x-C init(N * 3); int ans = 0; for (int i = 0; i < K; i++) { int t = T[i]; int x = X[i] - 1, y = Y[i] - 1; //把輸入變成 0, ... , N-1 範圍 //不正確的編號 if (x < 0 || x >= N || y < 0 || y >= N) { ans++; continue; } if (t == 1) { //"x和y屬於同一類"的信息 if (same(x, y + N) || same(x, y + 2*N)) { ans++; } else { //同屬A,或B,或C類 unite(x, y); unite(x + N, y + N); unite(x + 2*N, y + 2*N); } } else { //"x吃y"的信息錯,同為一類,或者隔了1類 if (same(x, y) || same(x, y + 2*N)) { ans++; } else { unite(x, y + N); // A -> B unite(x + N, y + 2 * N); // B -> C unite(x + 2 * N, y); // C -> A } } } printf("%d\n", ans); } int main() { solve(); return 0; }

並查集:POJ 1182 食物鏈 復習