当前位置:软件学习 > Word >>

Uva 10129 - Play on Words 单词接龙 欧拉道路应用

跟Uva 10054很像,不过这题的单词是不能反向的,所以是有向图,判断欧拉道路。

关于欧拉道路(from Titanium大神):

判断有向图是否有欧拉路
1.判断有向图的基图(即有向图转化为无向图)连通性,用简单的DFS即可。如果图都不连通,一定不存在欧拉路
2.在条件1的基础上
  对于欧拉回路,要求苛刻一点,所有点的入度都要等于出度,那么就存在欧拉回路了
  对于欧拉道路,要求松一点,只有一个点,出度比入度大1,这个点一定是起点; 一个点,入度比出度大1,这个点一定是终点.其余点的出度等于入度
 (注意,只能大1,而且这样的点分别只能有1个,而且存在起点就一定要存在终点,存在终点就一定要存在起点)

他用判断连通性用的是DFS,我用的是并查集实现。

然后判断为欧拉回路(入度=出度)或者欧拉道路(出入度相差1的点只有不同的两个)(而且其他点出度=入度!)。

 


代码:

 
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
const int maxn = 30; 
int f[maxn], g[maxn][maxn], id[maxn], od[maxn]; 
int t, n, root; 
 
int Find(int x) { 
    if (x != f[x])  
        return f[x] = Find(f[x]); 
    return x; 
} 
 
int main () { 
    scanf("%d", &t); 
    while (t--) { 
        char word[1001]; 
        scanf("%d", &n); 
        for (int i = 0; i < maxn; i++) { 
            f[i] = i; 
            id[i] = 0; 
            od[i] = 0; 
            for (int j = 0; j < maxn; j++) 
                g[i][j] = 0; 
        } 
        for (int i = 0; i < n; i++) { 
            scanf("%s", word); 
            int a = word[0] - 'a', b = word[strlen(word) - 1] - 'a'; 
            g[a][b]++; 
            od[a]++; 
            id[b]++; 
            f[Find(a)] = Find(b); 
            root = Find(b); 
        } 
        int i, ans = 0, flag = 1, in = 0, on = 0; 
        for (i = 0; i < maxn; i++) 
        if (id[i] || od[i]) { 
            if (Find(f[i]) != root) 
                ans++; 
            if (id[i] - od[i] == 1) 
                in++; 
            else if (od[i] - id[i] == 1) 
                on++; 
            else if (abs(id[i] - od[i]) > 1) 
                break; 
        } 
//      printf("%d %d %d %d\n", i, ans, in, on);  
        if (i < maxn || ans > 0 || in > 1 || on > 1) 
            printf("The door cannot be opened.\n"); 
        else 
            printf("Ordering is possible.\n"); 
    }//while  
    return 0; 
} 

#include <cstdio>
#include <cstdlib>
#include <cstring>
const int maxn = 30;
int f[maxn], g[maxn][maxn], id[maxn], od[maxn];
int t, n, root;

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

int main () {
 scanf("%d", &t);
 while (t--) {
  char word[1001];
  scanf("%d", &n);
  for (int i = 0; i < maxn; i++) {
   f[i] = i;
   id[i] = 0;
   od[i] = 0;
   for (int j = 0; j < maxn; j++)
    g[i][j] = 0;
  }
  for (int i = 0; i < n; i++) {
   scanf("%s", word);
   int a = word[0] - 'a', b = word[strlen(word) - 1] - 'a';
   g[a][b]++;
   od[a]++;
   id[b]++;
   f[Find(a)] = Find(b);
   root = Find(b);
  }
  int i, ans = 0, flag = 1, in = 0, on = 0;
  for (i = 0; i < maxn; i++)
  if (id[i] || od[i]) {
   if (Find(f[i]) != root)
    ans++;
   if (id[i] - od[i] == 1)
    in++;
   else if (od[i] - id[i] == 1)
     on++;
   else if (abs(id[i] - od[i]) > 1)
    break;
  }
//  printf("%d %d %d %d\n", i, ans, in, on);
  if (i < maxn || ans > 0 || in > 1 || on > 1)
   printf("The door cannot be opened.\n");
  else
   printf("Ordering is possible.\n");
 }//while
 return 0;
}

 

 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,