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;
}