poj2337(gcc)

poj2337 歐拉路問題  
通過並查集判定圖是否連通;根據條件判定是否存在歐拉路,即或者所有頂點的入度和出度相等,或者有且僅有兩個頂點,一個頂點的入度等於出度加一,另一個頂點的入度加一等於出度;通過深搜求出歐拉路徑。這道題目將每個單詞的首尾字母抽象成頂點,當兩個頂點屬於同一個單詞時,則存在一條單詞頭部字母對應的頂點指向單詞尾部字母對應的頂點的弧,存儲採用了鄰接表的方式,數組adj是頭部數組,node對應的adjlist數組則存儲對應鄰接邊。
#include 
#include 
#include 
#define maxn 1001
#define num 26
typedef struct node{
	int next, adj;
	char word[21];
}node;
node adjlist[maxn];
int adj[num];
int deg[num];
int vis[maxn];
int top, stack[maxn];
int tree[num];
int et[num];

int findRoot(int u){
	if(tree[u] == -1)	return u;
	int v = findRoot(tree[u]);
	tree[u] = v;
	return v;
}

int cmp(const void *x, const void *y){
	node *_x = (node *)x;
	node *_y = (node *)y;
	return strcmp(_y->word, _x->word);
}
void createGrapic(){
	int i, e;
	scanf("%d", &e);
	for(i = 0; i < e; ++i)
		scanf("%s", adjlist[i].word);
	memset(adj, -1, sizeof(adj));
	memset(deg, 0, sizeof(deg));
	memset(vis, 0, sizeof(vis));
	memset(tree, -1, sizeof(tree));
	memset(et, 0, sizeof(et));
	qsort(adjlist, e, sizeof(node), cmp);
	for(i = 0; i < e; ++i){
		int len = strlen(adjlist[i].word);
		int start = adjlist[i].word[0]-'a', end = adjlist[i].word[len-1]-'a';
		--deg[start];
		++deg[end];
		adjlist[i].next = adj[start];
		adj[start] = i;
		adjlist[i].adj = end;
		et[start] = 1; et[end] = 1;
		int p = findRoot(start);
		int q = findRoot(end);
		if(p != q)
			tree[p] = q;
	}
}

void euler(int u){
	int v;
	for(v = adj[u]; v != -1; v = adjlist[v].next){
		if(!vis[v]){
			vis[v] = 1;
			euler(adjlist[v].adj);
			stack[top++] = v;
		}
	}
}

int main(){
	int i, N, w;
	scanf("%d", &N);
	while(N--){
		w = 0;
		createGrapic();
		for(i = 0; i < num; ++i){
			if(et[i])	if(tree[i] == -1)	++w;
		}	
		if(w > 1){	printf("***\n");	continue;}
		top = 0;
		int pos = 0, neg = 0, oth = 0, k, flag = 0;
		for(i = 0; i < num; ++i)
			if(deg[i] == 1)	++pos; 
			else	if(deg[i] == -1)	{++neg; k = i;}
			else	if(deg[i] != 0)		++oth;
		if(neg==0 && pos==0 && oth==0){
			for(i = 0; i < num; ++i)
				if(adj[i] != -1){euler(i); flag = 1; break;}	
		}
		else	if(neg==1 && pos==1 && oth==0){euler(k); flag = 1;}
		else	printf("***\n");
		if(flag){
			while(--top)	printf("%s.", adjlist[stack[top]].word);
			printf("%s\n", adjlist[stack[top]].word);
		}			
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章