您的位置:首页 > 其它

UVa 10054(欧拉回路)

2013-04-15 22:40 330 查看
这里普及一下欧拉回路的知识。

欧拉道路是指从图中的任意一个点开始遍历,每条边恰好经过一次,这样的道路就是欧拉道路。

如果能从任意一个点出发,并回到这个点,每条边恰好经过一次,这样的道路是欧拉回路。

欧拉道路的判定:在无向图中,最多只有度数为奇数的点,则一定存在欧拉道路,并且要从一个奇点出发,到另一个奇点结束;如果全部都是偶数度数的点,那么就一定存在欧拉回路。对于有向图,最多有两个点的入度不等于出度,其中的一个点的入度必须比出度大1,这个点作为终点,另个一点一定要出度比入度大1,作为起点;如果不存在出度和入度不等的点,那么就存在欧拉回路。但是前提一定要图是连通的。

接下来就是题目:有n个珠子,每个珠子有两半,一半一个颜色,要求相邻的两个珠子挨着的部分是颜色相同的那一半,问按照这样的要求,能不能组成一个项链。

分析:开始很直接就是把珠子作为节点,很难搞定。后来看了神书,把颜色作为节点,珠子作为边,就是珠子上的一个颜色和另一个颜色连一条边,但是要注意的是,可能一种珠子可能有好多个,所以注意重边的处理!然后就是每条边走一次,相当于珠子用过一次,然后从任意一个颜色开始,最后走回这个颜色,正好就是欧拉回路!

代码:

#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;

const int N = 60;
int n, T;
int g

, edge
;
bool iseu, vis

;
struct E{ int u, v; } tmp;
stack <E> st;

void euler( int u ) {
for ( int v = 1; v <= 50; ++v ) if ( g[u][v] ) {
g[u][v]--; g[v][u] = g[u][v];
euler( v );
tmp.u = u, tmp.v = v;
st.push(tmp);
}
}
int main()
{
scanf("%d", &T);
int icase = 1;
while ( T-- ) {
scanf("%d", &n);
memset( g, 0, sizeof(g) );
memset( vis, 0, sizeof(vis) );
memset( edge, 0, sizeof(edge) );
int s, e;
for ( int i = 0; i < n; ++i ) {
scanf("%d%d", &s, &e);
edge[s]++, edge[e]++;
g[s][e]++;
g[e][s] = g[s][e];
}
iseu = true;
for ( int i = 1; i <= 50; ++i ) if ( edge[i] % 2 == 1 ) iseu = false;
printf("Case #%d\n", icase++ );
if ( !iseu )
printf("some beads may be lost\n");
else {
euler( s );
while ( !st.empty() ) {
tmp = st.top(); st.pop();
printf("%d %d\n", tmp.u, tmp.v);
}
}
if ( T > 0 ) printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: