UVA - 10158 War 并查集升级版

来源:互联网 发布:sql语言具有查询功能吗 编辑:程序博客网 时间:2024/05/21 06:57

题目大意:题目好长,就不细说了

解题思路:解法1:设置两个数组,一个数组是并查集的基本数组p[maxn],另一个数组r[maxn]表示点和根节点的关系,0表示和根节点是朋友,1表示和根结点是敌人,那么在并查集的时候就可以顺便设置以下r数组了,这里用到的是向量思想,什么是向量思想,下面会给链接,这里就不解释了

点击打开链接

解法2:给每个人设置一个永远的敌人,他和他永远的敌人不在同一个集合,然后只要结合这四个点进行判断即可

解法1代码:

#include<stdio.h>#include<string.h>#define MAXN 10010int N, p[MAXN], delta[MAXN];int find(int x){    if(p[x] == x)        return x;    int tx = find(p[x]);    delta[x] =(delta[x] + delta[p[x]]) % 2;    p[x] = tx;    return tx;}void init(){    int i, x, y, tx, ty, flag;    for(i = 0; i < N; i ++)    {        p[i] = i;        delta[i] = 0;    }    for(;;)    {        scanf("%d%d%d", &flag, &x, &y);        if(!x && !y && !flag)            break;        tx = find(x);        ty = find(y);        if(flag == 3)        {            if(tx != ty || delta[x] != delta[y])                printf("0\n");            else                printf("1\n");        }        else if(flag == 4)        {            if(tx != ty || delta[x] == delta[y])                printf("0\n");            else                printf("1\n");        }        else if(flag == 1)        {            if(tx == ty)            {                if(delta[x] != delta[y])                    printf("-1\n");            }            else            {                p[tx] = ty;                delta[tx] = (delta[x] - delta[y] + 2) % 2;            }        }        else if(flag == 2)        {            if(tx == ty)            {                if(delta[x] == delta[y])                    printf("-1\n");            }            else            {                p[tx] = ty;                delta[tx] = (delta[x] - delta[y] + 1) % 2;            }        }    }}int main(){    while(scanf("%d", &N) == 1)    {        init();    }    return 0;}

解法2代码:

#include<cstdio>#include<cstring>#define maxn 20020int p[maxn],x1,x2,y1,y2,N;int find(int x) {return x == p[x] ? p[x]:p[x] = find(p[x]);}int main() {scanf("%d",&N);for(int i = 0; i <= 2 * N; i++)p[i] = i;int c,x,y;while(scanf("%d%d%d",&c,&x,&y) != EOF && c + x + y) {x1 = find(x); y1 = find(x + N);x2 = find(y); y2 = find(y + N);if(c == 1) {//如果x和y的敌人是朋友if(x1 == y2) {printf("-1\n");continue;}//如果x和y是朋友,那么x的敌人就是y的敌人的朋友,y的敌人就是x的敌人的朋友p[x1] = x2; p[y1] = y2;}if(c == 2) {//如果x和y是朋友if(x1 == x2) { printf("-1\n");continue;}//如果x和y是敌人,那么x的敌人就是y的朋友,y的敌人就是x的朋友p[x1] = y2;p[x2] = y1;}if(c == 3) {if(x1 == x2)printf("1\n");elseprintf("0\n");}if(c == 4) {if(x1 == y2)printf("1\n");elseprintf("0\n");}}return 0;}





0 0