题意:有N个人,属于两个不同的帮派,给出一定的条件,让你判断这两个人是否属于同一帮派。
思路:刚开始知道要用到并查集,但读懂题意后又觉得有点小麻烦,比如说给出D 1 2 ,D 3 4 ,怎样确定到底是1,3 在同一帮派,还是1,4在同一帮派,想先将所有人放在一起,然后判断出了两人属于不同帮派就分出来,但是这样依然不好处理上面那个问题,想来想去,还是没有好的想法,参考了一下别人的思路,豁然开朗。其实何必纠结到底是那两个人一个帮派呢,只要知道1和2 是不同帮派就行了,开一个数组,专门用来存X的相反帮派的序号,如果以前没有提供X的相反的人,那就置为0,如果已经知道X的相反人的序号,就把它与Y相连,以此类推。
代码:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #include <math.h> #define N 100005 using namespace std ; int f[N] , opp[N] ; void init( int n ) { int i ; for ( i = 0 ; i <= n ; i++ ) { f[i] = i ;opp[i] = 0 ; } } int find( int x ) { if ( x != f[x] ) f[x] = find ( f[x] ); return f[x] ; } void unit( int x , int y ) { int xx = find ( x ); int yy = find ( y ); if ( xx != yy ) f[xx] = yy ; } int main() { int cas , n , m , x , y , i ; char c ; cin>>cas ; while( cas-- ) { scanf ( "%d%d" , &n , &m ) ; //cin>>n>>m ; getchar(); init( n ) ; for ( i = 0 ; i < m ; i++ ) { scanf ( "%c %d %d" , &c , &x , &y ); getchar(); if ( c == 'D' ) { if ( !opp[x] && !opp[y] ) { opp[x] = y ; opp[y] =x ; } else if ( !opp[x] ) { opp[x] = y ; unit( x , opp[y] ); } else if ( !opp[y] ) { opp[y] = x; unit( y , opp[x] ); } else { unit( x , opp[y] ) ; unit( y , opp[x] ) ; } } else if ( c == 'A' ) { if ( find ( x ) == find ( y )) printf ( "In the same gang.\n" ); else if ( find( x ) == find ( opp[y] )) printf ( "In different gangs.\n" ) ; else printf ( "Not sure yet.\n" ); } } } return 0 ; }
再说一句,cin 输入很慢,全用cin输入会超时。