一个简单的并查集的题目,要注意的是内部权值的修改。
#include  < stdio.h >

int  num[ 100001 ];
int  dis[ 100001 ];

void  init( int  p)
{

    
int i;
    
for (i=0; i<p; i++)
    
{
        num[i] 
= -1;
        dis[i] 
= 0;
    }

}


int  find( int  a)
{

    
int i = a;
    
int count = 0;
    
int temp;

    
while (num[i]>=0)
    
{
        count 
+= dis[i];
        i 
= num[i];
    }

    
while (a!=i)
    
{
        count 
-= dis[a];
        dis[a] 
+= count;
        temp 
= a;
        a 
= num[a];
        num[temp] 
= i;
    }


    
return i;
}


void  un( int  a,  int  b)
{
    
    
int ra = find(a);
    
int rb = find(b);

    
if(num[ra]<=num[rb])
    
{
        num[ra] 
+= num[rb];
        num[rb] 
= ra;
        dis[rb] 
= dis[a] -dis[b] +1;
    }

    
else
    
{
        num[rb] 
+= num[ra];
        num[ra] 
=rb;
        dis[ra] 
= dis[b] - dis[a] -1;
    }

}


int  main()
{

    
int t, n, m;
    
int l, rl, r, rr;
    
char ch[3];
    scanf(
"%d"&t);
    
while (t--)
    
{
        scanf(
"%d%d"&n, &m);
        
        init(n);
        
while (m--)
        
{
            scanf(
"%s%d%d"&ch, &l, &r);

            rl 
= find(l-1);
            rr 
= find(r-1);
            
if (ch[0]=='D')
            
{
                
if(rl!=rr)
                
{
                    un(l
-1, r-1);
                }

            }

            
else
            
{
                
                
if (rl!=rr)
                
{
                    printf(
"Not sure yet.\n");
                }

                
else
                
{
                    
if (dis[l-1]%2==dis[r-1]%2 || dis[l-1]%2==-dis[r-1]%2)
                    
{
                        printf(
"In the same gang.\n");
                    }

                    
else
                    
{
                        printf(
"In different gangs.\n");
                    }

                }

            }

        }

    }

    
return 0;
}

地址: http://acm.pku.edu.cn/JudgeOnline/problem?id=1703