练习题 No.20 食物链

来源:互联网 发布:seo原创软文代写兼职 编辑:程序博客网 时间:2024/05/23 21:41

要求

有N只动物,分别编号为1,2,…,N。所有动物都属于A,B,C中的其中一种。已知A吃B、B吃C、C吃A。按顺序给出下面的二种信息共K条
* 第一种:x和y属于同一种类
* 第二种:x吃y
然而这些信息有可能会出错。有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的x和y不在1,2,…,N的范围内。求在K条信息中有多少条是不正确的。计算过程中,我们将忽视诸如此类的错误信息。

限制条件

  • 1 <= N <= 50000
  • 0 <= K <= 100000

输入格式

第一行输入N,K
接下来K行输入
第几种信息(1,2) 编号a 编号b

输出格式

输出有多少条是不正确的

测试输入

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

测试输出

3

解题思路

用并查集进行实现,分别扩展par数组为N * 3 ,用来记录A、B、C

代码

#include <iostream>#include <cmath>using namespace std;  int par[150001];int rank[150001];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]);    }}void unite(int x, int y) {    x = find(x);    y = find(y);    if (x == y) {        return;    } else 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); } int N, K;int T[1001], X[1001], Y[1001];int main() {    cin >> N;    cin >> K;    for (int i = 0; i < K; i++) {        cin >> T[i] >> X[i] >> Y[i];    }        init(N * 3);    int ans = 0;    for (int i = 0; i < K; i++) {        int t = T[i];        int x = X[i] - 1;        int y = Y[i] - 1;        if (x < 0 || N <= x || y < 0 || N <= y) {            ans++;            continue;        }        if (t == 1) {            if (same(x, y + N) || same(x, y + 2 * N)) {                ans++;            } else {                unite(x, y);                unite(x + N, y + N);                unite(x + N * 2, y + N * 2);            }        } else {            if (same(x, y) || same(x, y + 2 * N)) {                ans++;            } else {                unite(x, y + N);                unite(x + N, y + 2 * N);                unite(x + 2 * N, y);            }        }    }    cout << ans << endl;    return 0;  }
0 0