poj2513(trie树+欧拉路+并查集)

  题目的大意就是一根木棍两端涂上颜色,然后要把所有的木棍连成一根木棍,然后两根木棍能合并的前提是,连在一起的两端是同样一种颜色,然后这个额就很好理解,是一边画问题,求是否有欧拉路出现就好。

  无向图有欧拉路的条件:

  1.有0个或者2个点的度数为奇数。

  2.图是一个连通图。

  

  然后判断图连通,就是运用并查集的方法,每次合并一条边的两个顶点,最终一个连通图会合并成一个顶点,一个非连通图会合并成多个顶点,然后还要用路径压缩的方法,压缩一下路径。


  然后查找每一个单词的索引,由于数据量比较大,map可能比较慢,运用Trie树进行索引查找。

  

  题目有一个坑点是,可能里面有空数据,还要输出Possible。

  

#include "stdio.h"
#include "string.h"
#include "math.h"
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;

#define MAXM 1
#define MAXN 1
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
#define Mem(a,b) memset(a,b,sizeof(a))
int Mod = 1000000007;
double pi = acos(-1.0);
double eps = 1e-6;

typedef struct{
	int f,t,w,next;
}Edge;
Edge edge[MAXM];
int head[MAXN];
int kNum;

void addEdge(int f, int t, int w)
{
	edge[kNum].f = f;
	edge[kNum].t = t;
	edge[kNum].w = w;
	edge[kNum].next = head[f];
	head[f] = kNum ++;
}

char s1[15], s2[15];
int father[500005];
int indree[500005];


struct Node{
	bool flag;
	int id;
	struct Node *next[27];
	Node(){
		flag = false;
		id = -1;
		Mem(next, NULL);
	}
};

int find(int x){
	int s = x;
	while( father[x] != x ) x = father[x];
	for(int p = s; p != x; p = s){
		s = father[p];
		father[p] = x;
	}
	return x;
}

void Union(int x, int y){
	if( x < y ){
		father[y] = x;
	}
	else
		father[x] = y;
}

void solve(){
	kNum = 0;
	Mem(indree,0);

	struct Node* root = new struct Node;
	int id1, id2;
	while( scanf("%s %s", s1, s2) != EOF ){
//		getchar();
		struct Node *p = root;
		for(int i = 0; s1[i] != 0; i ++){
			if( p->next[s1[i] - 'a']  == NULL ){
				p->next[s1[i] - 'a'] = new struct Node; 
			}
			p = p->next[s1[i] -'a'];
		}
		if( !p->flag ){
			p ->flag = true;
			p ->id = kNum ++;
			father[p->id] = p->id;
		}
		id1 = p->id;

		p = root;
		for(int i = 0; s2[i] != 0; i ++){
			if( p->next[s2[i] - 'a']  == NULL ){
				p->next[s2[i] - 'a'] = new struct Node; 
			}
			p = p->next[s2[i] -'a'];
		}
		if( !p->flag ){
			p ->flag = true;
			p ->id = kNum ++;
			father[p->id] = p ->id;
		}
		id2 = p ->id;

		indree[id1] ++, indree[id2] ++;

		id1 = find(id1);
		id2 = find(id2);

		if( id1 != id2 ){
			Union(id1, id2);
		}

	}

	int num = 0;
	int s = find(0);
	for(int i = 0; i < kNum; i ++){
		if( indree[i] % 2 )
			num ++;
		if( num > 2 ){
			printf("Impossible\n");
			break;
		}
		if( find(i) != s ){
			printf("Impossible\n");
			break;
		}
		if( i == kNum - 1 ){
			if( num == 1 ){
				printf("Impossible\n");
			}
			else{
				printf("Possible\n");
			}
		}
	}
	if( kNum == 0 ){
		printf("Possible\n");
	}

}


int main()
{
//	freopen("d:\\test.txt", "r", stdin);

	solve();

	return 0;
}

    原文作者:Trie树
    原文地址: https://blog.csdn.net/kevin_liu11/article/details/46372385
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞