hdoj3926-Hand in Hand(同构图的判断)

题目链接

思路

 

1.这个图就是同构图的判断,对于题目中的孩子的牵手方式,因为每个人只有两只手,所以可以看成图中每个节点的读书不大于2,因此连接方式只能是环或者链; 
2.然后我们只用并查集来判断每个图含有多少环,多少链,然后对于环和链,用其中的一个节点来记录环或者链所含有节点个数; 
3.然后将所有节点按是否成环和节点的数目来排序,最后再遍历判断一次结果。

code

#include <iostream>
 #include <algorithm>
 #include <cstring>
 #include <fstream>
using namespace std;

const int MAX = 10005;

class Node{
	public: 
		int isCircle, count;//是否成环,以及节点的个数
};

Node node1[MAX], node2[MAX];
int f[MAX];

int cmp(Node a, Node b) {
	if(a.isCircle == b.isCircle) {
		return a.count > b.count;
	} 
	return a.isCircle > b.isCircle;
}

void init() {
	for(int i = 0; i < MAX; ++ i) {
		f[i] = i;
	}
}

int find(int x) {
	if(x != f[x]) {
		f[x] = find(f[x]);
	}
	return f[x];
}

int main() {
    //ifstream cin("data.in");
    int t, cnt = 1;
    cin >> t;
    while(t --)
    {
        int n1, n2, m1, m2;
        bool ok = true;   
        for(int i = 0; i < MAX; ++ i) {
        	node1[i].isCircle = 0;//初始化每个孩子为单独个体,且不成环,看做节点数为1的链
        	node2[i].isCircle = 0;
        	node1[i].count = 1;
        	node2[i].count = 1;
        }
		cin >> n1 >> m1;
        init();
        for(int i = 0; i < m1; i ++) {
        	int x, y;
        	cin >> x >> y;
        	x = find(x);
        	y = find(y);
        	if(x != y) {   //当两条链不成环时,连接两条链
        		f[y] = x;
        		node1[x].count += node1[y].count;
        		node1[y].count = 0;
        	}
        	else {
        		node1[y].isCircle = 1;//成环时进行标记
        	}
        }
        cin >> n2 >> m2;
        init();
        for(int i = 0; i < m2; i ++) {
        	int x, y;
        	cin >> x >> y;
        	x = find(x);
        	y = find(y);
        	if(x != y) {
        		f[y] = x;
        		node2[x].count += node2[y].count;
        		node2[y].count = 0;
        	}
        	else {
        		node2[y].isCircle = 1;
        	}
        }
        if(n1 != n2 || m1 != m2) {
        	ok = false; 
        }
        else {
        	sort(node1+1, node1+n1+1, cmp);
        	sort(node2+1, node2+n2+1, cmp);
        	for(int i = 1; i < n1; i ++) {
        		if(node1[i].isCircle != node2[i].isCircle || node1[i].count != node2[i].count){
        			ok = false;
        			break;
        		}
        	}
        }
        cout << "Case #" << cnt ++ << ": ";
        if(ok) {
        	cout << "YES" << endl;
        }
        else {
        	cout << "NO" << endl;
        }
    }
    return 0;
}




posted @ 2016-11-22 20:42  zq216991  阅读(155)  评论(0编辑  收藏  举报