URAL_1003

    这个题目可以用并查集做,类似“食物链”的题目。只不过由于N的范围比较大,一开始可以先离散化一下。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXD 100010
int N, Q, a[MAXD], p[MAXD], d[MAXD];
struct Que
{
    int x, y;
    char b[5];
}que[MAXD];
int cmp(const void *_p, const void *_q)
{
    int *p = (int *)_p, *q = (int *)_q;
    return *p < *q ? -1 : 1;
}
int find(int x)
{
    int fa;
    if(p[x] == x)
        return x;
    fa = find(p[x]);
    d[x] = (d[x] + d[p[x]]) % 2, p[x] = fa;
    return fa;
}
void init()
{
    int i, j, k;
    scanf("%d", &Q);
    for(i = 0; i < Q; i ++)
    {
        scanf("%d%d%s", &que[i].x, &que[i].y, que[i].b);
        a[i * 2 + 1] = que[i].x, a[i * 2 + 2] = que[i].y;
    }
    qsort(a, 2 * Q, sizeof(a[0]), cmp);
    a[0] = N = 0;
    for(i = 1; i <= 2 * Q; i ++)
        if(a[i] != a[i - 1])
            a[++ N] = a[i];
}
int BS(int x)
{
    int min = 1, max = N + 1, mid;
    for(;;)
    {
        mid = (min + max) >> 1;
        if(min == mid)
            break;
        if(a[mid] <= x)
            min = mid;
        else
            max = mid;
    }
    return mid;
}
void solve()
{
    int i, j, k, x, y, tx, ty, delta;
    for(i = 0; i <= N; i ++)
        p[i] = i, d[i] = 0;
    for(i = 0; i < Q; i ++)
    {
        x = BS(que[i].x) - 1, y = BS(que[i].y);
        tx = find(x), ty = find(y), delta = que[i].b[0] == 'e' ? 0 : 1;
        if(tx != ty)
            p[ty] = tx, d[ty] = (delta + d[x] - d[y] + 2) % 2;
        else
        {
            if(d[y] != (d[x] + delta) % 2)
                break;
        }
    }
    printf("%d\n", i);
}
int main()
{
    for(;;)
    {
        scanf("%d", &N);
        if(N == -1)
            break;
        init();
        solve();
    }
    return 0;
}
posted on 2012-04-30 01:44  Staginner  阅读(356)  评论(0编辑  收藏  举报