http://acm.pku.edu.cn/JudgeOnline/problem?id=1182

Код:
#include <stdio.h>
#include <memory.h>

const int MAXN =  50010;
int v[3*MAXN];

int FIND(int x)
{
    if ( x!=v[x] )
        v[x] = FIND(v[x]);
    return v[x];
}

int same(int x, int y);
int kill(int x, int y);

int n, k;
int main()
{
    scanf("%d %d", &n, &k);
    int i;
    int d, x, y;
    int res = 0;
    for(i = 0; i < 3*n; i++)
            v[i] = i;
    for(i = 0; i < k; i++)
    {
        scanf("%d %d %d", &d, &x, &y);
        x--; y--;
        if ( x>=n||y>=n )
        {
            res++;
            continue;
        }
        if ( d==1 ) res += same(x, y);
        else res += kill(x, y);
    }
    printf("%d\n", res);
    return 0;
}

int next(int x)
{
    return (x+n)%(3*n);
}
int prev(int x)
{
    return (x+2*n)%(3*n);
}

int same(int x, int y)
{
    int a = FIND(x);
    int b = FIND(y);
    if ( (a%n)==(b%n) && (a!=b) )
        return 1;
    v[b] = a;
    v[prev(b)] = prev(a);
    v[next(b)] = next(a);
    return 0;
}

int kill(int x, int y)
{
    int a = FIND(next(x));
    int b = FIND(y);
    if ( (a%n)==(b%n) && (a!=b) )
        return 1;
    a = FIND(x);
    v[b] = next(a);
    v[prev(b)] = a;
    v[next(b)] = prev(a);
    return 0;
}