SGU 101 Domino

SGU_101

    这个可以把骨牌看成一条边,把数字看成点,这样最后实际上就是去求一条欧拉道路。

    对于无向图欧拉道路要求:①图必须连通;②度数为奇数的点没有或者只有两个。

    不符合上述要求自然就无解了,如果有解选一个度数为奇数的点(如果没有就任取一个点)用dfs遍历一遍图把欧拉道路打印出来即可。

#include<stdio.h>
#include<string.h>
#define MAXD 10
#define MAXM 210
int N, e, first[MAXD], next[MAXM], v[MAXM], p[MAXD], dgr[MAXD], vis[MAXM];
int find(int x)
{
return p[x] == x ? x : (p[x] = find(p[x]));
}
void add(int a, int b)
{
v[e] = b;
next[e] = first[a];
first[a] = e;
e ++;
}
void init()
{
int i, j, k, a, b, x, y;
e = 0;
memset(first, -1, sizeof(first));
memset(dgr, 0, sizeof(dgr));
for(i = 0; i < 7; i ++)
p[i] = i;
for(i = 0; i < N; i ++)
{
scanf("%d%d", &a, &b);
dgr[a] ++, dgr[b] ++;
x = find(a), y = find(b);
if(x != y)
p[y] = x;
add(a, b);
add(b, a);
}
}
void printpath(int u)
{
int i;
for(i = first[u]; i != -1; i = next[i])
if(!vis[i])
{
vis[i] = vis[i ^ 1] = 1;
printpath(v[i]);
printf("%d %c\n", i / 2 + 1, i % 2 ? '+' : '-');
}
}
void solve()
{
int i, j, k, num, ok, start;
num = 0;
for(i = 0; !dgr[i]; i ++);
start = i;
ok = 1;
for(j = i; j < 7; j ++)
{
if(dgr[j] && find(start) != find(j))
{
ok = 0;
break;
}
if(dgr[j] % 2)
{
num ++;
start = j;
}
}
if(num > 2)
ok = 0;
if(!ok)
{
printf("No solution\n");
return ;
}
memset(vis, 0, sizeof(vis));
printpath(start);
}
int main()
{
while(scanf("%d", &N) == 1)
{
init();
solve();
}
return 0;
}


原文地址:https://www.cnblogs.com/staginner/p/2282566.html