POJ-2513(trie+并查集+欧拉回路)

自认为此题有个bug

#define NUMBER 500005
int p[NUMBER + 5];
int rank[NUMBER + 5];
void make_set(int x) {
	p[x] = x;
	rank[x] = 0;
}
int find_set(int x) {
	if (x != p[x]) p[x] = find_set(p[x]);
	return p[x];
}
void link_set(int x, int y) {
	if (rank[x] > rank[y]) p[y] = x;
	else {
		p[x] = y;
		if (rank[x] == rank[y]) ++rank[y];
	}
}
void union_set(int x, int y)
{
	link_set(find_set(x), find_set(y));
}
int Index;
int degree[NUMBER];
struct trie
{
    int cnt;
    trie *p[26];
} * root;
int make_tree(char *s)
{
    trie * r = root;
    trie * tmp;
    int i, j;
    for (i = 0; s[i] != '\0'; ++i) {
        if (r->p[s[i] - 'a'] == NULL) {
            tmp = new trie;
            tmp->cnt = -1;
            for (j = 0; j < 26; ++j)
                tmp->p[j] = NULL;
            r->p[s[i] - 'a'] = tmp;
        }
        r = r->p[s[i] - 'a'];
    }
	if (r->cnt == -1)
		r->cnt = Index++;
	return r->cnt;
}
int main()
{
	int i, j;
	root = new trie;    
	for (i = 0; i < 26; ++i)
		root->p[i] = NULL;
	for (i = 0; i < NUMBER; ++i)
		make_set(i);
	char a[15], b[15];
	char s[1000];
	int flag = 0;
	while (gets(s) != NULL && flag == 0) {
		memset(degree, 0, sizeof(degree));
		for (i = 0; i < NUMBER; ++i)
			make_set(i);
		root = new trie; 
		for (i = 0; i < 26; ++i)
			root->p[i] = NULL;
		Index = 0;
		while (strlen(s) != 0 && flag == 0) {
			sscanf(s, "%s %s", a, b);
			int x = make_tree(a);
			int y = make_tree(b);
			degree[x]++;
			degree[y]++;
			union_set(x, y);
			if (gets(s) == NULL)
				flag = 1;
		}
		int sum = 0;
		for (i = 0; i < Index; ++i) {
			if (degree[i] % 2 == 1)
				++sum;
		}
		if (sum == 0 || sum == 2) {
			int t = find_set(0);
			for (i = 1; i < Index; ++i) {
				if (find_set(i) != t) {
					break;
				}
			}
			if (i >= Index - 1) printf("Possible\n");///bugggggggggggggggggggggggggg
			else printf("Impossible\n");
		} else printf("Impossible\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值