Play on Words UVA - 10129 欧拉路径
Posted 天道酬勤007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Play on Words UVA - 10129 欧拉路径相关的知识,希望对你有一定的参考价值。
定义:
欧拉回路:每条边恰好只走一次,并能回到出发点的路径
欧拉路径:经过每一条边一次,但是不要求回到起始点
①首先看欧拉回路存在性的判定:
一、无向图
每个顶点的度数都是偶数,则存在欧拉回路。
二、有向图(所有边都是单向的)
每个节顶点的入度都等于出度,则存在欧拉回路。
②.欧拉路径存在性的判定
一。无向图
一个无向图存在欧拉路径,当且仅当 该图所有顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。
二。有向图
一个有向图存在欧拉路径,当且仅当 该图所有顶点的入度等于出度 或者 一个点出度比入度多一(起点) 一个点入度比出度多一(终点) 其他都为入度等于出度。
在已经知道存在的情况下,下面的程序用于输出路径;
如果是输出欧拉道路,那么参数必须是道路的起点; 另外打印的顺序是逆序的,因此真正使用时候,用push存入(u,v);
void euler(int u){
for(Int v = 0; v < n; v++){
if(G[u][v]&&!vis[u][v]){
vis[u][v] = vis[v][u]=1;
euler(v);
printf("%d %d\n",u,v);
}
}
}
上面的代码只适用于无向图,改成有向图只需要把vis[u][v] =vis[v][u] = 1 改成 vis[u][v]即可;
/** 题目:Play on Words UVA - 10129 链接:https://vjudge.net/problem/UVA-10129 题意:给定n个单词,排成一行,使单词的首部字母和上一个单词(如果存在)的尾部字母相同。问是否存在这样的一行序列满足要求。 思路: 首先保证不考虑方向的情况下图是连通的。 判断有向图是否存在欧拉路径。 1,所有的点入度等于出度。 2,一个点入度比出度多一,一个点出度比入度多一,其他点入度等于出度。 把每一个word的首字母和尾字母连一条有向的边。 */ #include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const int mod=1e9+7; const int maxn=1e2+5; const double eps = 1e-12; int T, n; char s[1005]; int in[30], ot[30]; int st[30]; int vis[30]; int Find(int x) { if(x==st[x]) return x; return st[x] = Find(st[x]); } void Merge(int x,int y) { int fx = Find(x); int fy = Find(y); if(fx>fy){ st[fx] = fy; }else st[fy] = fx; } int main() { cin>>T; while(T--) { scanf("%d",&n); memset(in, 0, sizeof in); memset(ot, 0, sizeof ot); memset(vis, 0, sizeof vis); for(int i = 0; i < 26; i++) st[i] = i; for(int i = 0; i < n; i++){ scanf("%s",s); int len = strlen(s); vis[s[0]-‘a‘] = vis[s[len-1]-‘a‘] = 1; Merge(s[0]-‘a‘,s[len-1]-‘a‘); ot[s[0]-‘a‘]++; in[s[len-1]-‘a‘]++; } int r; for(int i = 0; i < 26; i++){ if(vis[i]){ r = Find(i); } } int sign = 0; for(int i = 0; i < 26; i++){ if(vis[i]){ if(Find(i)!=r){ sign = 1; break; } } } if(sign){///不考虑方向,没有连通。 printf("The door cannot be opened.\n"); continue; } int flag1, flag2, flag3; flag1 = flag2 = flag3 = 0;///分别表示入度等于出度的点数,入度比出度多一的点数,出度比入度多一的点数。 for(int i = 0; i < 26; i++){ if(in[i]==ot[i]){ flag1++; } if(in[i]-ot[i]==1){ flag2++; } if(ot[i]-in[i]==1){ flag3++; } } if(flag1==26||((flag1==24)&&(flag2==1)&&(flag3==1))){ printf("Ordering is possible.\n"); }else printf("The door cannot be opened.\n"); } return 0; }
以上是关于Play on Words UVA - 10129 欧拉路径的主要内容,如果未能解决你的问题,请参考以下文章
Play on Words UVA - 10129 (欧拉回路)