UVA-10585 War(8.4.3)

D - War(8.4.3)
Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu
Submit  Status

Description

  A war is being lead between two countries, A and B. As a loyal citizen of C, you decide to help your country’s espionage by attending the peace-talks taking place these days (incognito, of course). There are n people at the talks (not including you), but you do not know which person belongs to which country. You can see people talking to each other, and through observing their behaviour during their occasional one-to-one conversations, you can guess if they are friends or enemies. In fact what your country would need to know is whether certain pairs of people are from the same country, or they are enemies. You may receive such questions from C’s government even during the peace-talks, and you have to give replies on the basis of your observations so far. Fortunately nobody talks to you, as nobody pays attention to your humble appearance.

 

  Abstract

    Now, more formally, consider a black box with the following operations:

               setFriends(x, y)     shows that x and y are from the same country

               setEnemies(x, y)   shows that x and y are from different countries

               areFriends(x, y)     returns true if you are sure that x and y are friends

               areEnemies(x, y)   returns true if you are sure that x and y are enemies

    The first two operations should signal an error if they contradict with your former knowledge. The two relations ‘friends’ (denoted by ~) and ‘enemies’ (denoted by *) have the following properties:

              ~ is an equivalence relation, i.e.

1.      If x ~ y and y ~ z then x ~ z  (The friends of my friends are my friends as well.)

2.      If x ~ y then y ~ x                  (Friendship is mutual.)

3.      x ~ x                                       (Everyone is a friend of himself.)

              * is symmetric and irreflexive

4.      If x * y then y * x                  (Hatred is mutual.)

5.      Not x * x                                (Nobody is an enemy of himself.)

              Also

6.      If x * y and y * z then x ~ z   (A common enemy makes two people friends.)

7.      If x ~ y and y * z then x * z   (An enemy of a friend is an enemy.)

    Operations setFriends(x, y) and setEnemies(x, y) must preserve these properties.

 

 

  Input

     The first line contains a single integer, n, the number of people.

     Each of the following lines contains a triple of integers, c x y, where c is the code of the operation:

            c = 1, setFriends

            c = 2, setEnemies

            c = 3, areFriends

            c = 4, areEnemies

     and x and y are its parameters, which are integers in the range [0, n), identifying two (different) people. The last line contains 0 0 0.

    All integers in the input file are separated by at least one space or line break.

 

  Output

     For every ‘areFriends’ and ‘areEnemies’ operation write 0 (meaning no) or 1 (meaning yes) to the output. Also for every ‘setFriends’ or ‘setEnemies’ operation which contradicts with previous knowledge, output a –1 to the output ; note that such an operation should produce no other effect and execution should continue. A successful ‘setFriends’ or ‘setEnemies’ gives no output.

    All integers in the output file must be separated by at least one space or line break.

 

  Constraints

    n < 10000, the number of operations is unconstrained.

 

 

  Sample Input

            10

            1 0 1

            1 1 2

            2 0 5

            3 0 2

            3 8 9

            4 1 5

            4 1 2

            4 8 9

            1 8 9

            1 5 2

            3 5 2

            0 0 0

 

  Sample Output

            1

            0

            1

            0

            0

            -1

            0

 解题思路:

设:

set[k]表示k的朋友所在集合的代表元素;set[k+n]表示k的敌人所在集合的代表元素。

初始时所有人未确定敌我关系,即set[k]的初值为-1,(1<=k<=2n);

函数set_find(p);查找p所在集合的代表元素,及计算set[p];

函数arefriends(x,y);判断x,y的关系。若x和y关系未确定,即(set_find(x)!=set_find(y)&&set_find(x)!=set_find(y+n));arefriends(x,y)返回-1;

若x和y是朋友,即set_find(x)==set_find(y);则函数返回1.若x和y是敌人,

set_find(x)!=set_find(y);则返回0.

1,操作代码1 x y

在预先得知x和y来自同一个国家的情况下,若(x,y)是敌人即arefriends(x,y)=0;则新旧信息矛盾;

若(x,y)关系未确定即arefriends(x,y)=-1;则将x所在集合和y所在集合合并,x的敌人所在集合和

y的敌人所在集合合并。(set[set_find(x)]=set_find(y); set[set_find(x+n)]=set_find(y+n)).

2, 操作代码2 x y

在预先得知x和y来自不同一个国家的情况下,若(x,y)是朋友即arefriends(x,y)=1;则新旧信息矛盾;

若(x,y)关系未确定即arefriends(x,y)=-1;则将x所在集合和y的敌人所在集合合并,x的敌人所在集合和

y所在集合合并。(set[set_find(x)]=set_find(y+n); set[set_find(x+n)]=set_find(y)).

3,操作代码3 x y

直接根据arefriends(x,y)的值确定x和y是否为朋友。

4,操作代码4 x y

直接根据arefriends(x,y)的值确定x和y是否为敌人。

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=10000+5;
int set[maxn],n;
int set_find(int p)
{
    if(set[p]<0)
        return p;
    return set[p]=set_find(set[p]);
}
int arefriends(int x,int y)
{
    if((set_find(x)!=set_find(y))&&(set_find(x)!=set_find(y+n)))
        return -1;
        if(set_find(x)==set_find(y))
        return 1;
    if(set_find(x)!=set_find(y))
    return 0;


}
int main()
{
    int c,x,y;
    while(scanf("%d",&n)!=EOF){
    memset(set,-1,sizeof(set));
    while(scanf("%d %d %d",&c, &x, &y))
    {
        if(c==0&&x==0&&y==0)
          break;
        if(c==1)
        {
            if(arefriends(x,y)==0)
                cout<<-1<<endl;
            if(arefriends(x,y)==-1)
            {
                set[set_find(x)]=set_find(y);
                set[set_find(x+n)]=set_find(y+n);
            }
        }
        if(c==2)
        {
            if(arefriends(x,y)==1)
                cout<<-1<<endl;
            if(arefriends(x,y)==-1)
            {
                set[set_find(x)]=set_find(y+n);
                set[set_find(x+n)]=set_find(y);
            }
        }
        if(c==3)
        {
            if(arefriends(x,y)==1)
                cout<<1<<endl;
            else
                cout<<0<<endl;
        }
        if(c==4)
        {
            if(arefriends(x,y)==0)
                cout<<1<<endl;
            else
                cout<<0<<endl;
        }
    }
    }
    return 0;
}




你可能感兴趣的:(UVA-10585 War(8.4.3))