You have a set of dominoes. Each domino is a rectangular tile with a line dividing its face into two square ends. Can you put all dominoes in a line one by one from left to right so that any two dominoes touched with the sides that had the same number of points? You can rotate the dominoes, changing the left and the right side (domino "1-4" turns into "4-1").
The first line contains number n (1 ≤ n ≤ 100). Next n lines contains the dominoes. Each of these lines contains two numbers — the number of points (spots) on the left and the right half, correspondingly. The numbers of points (spots) are non-negative integers from 0 to 6.
Print "No solution", if it is impossible to arrange the dominoes in the required manner. If the solution exists, then describe any way to arrange the dominoes. You put the dominoes from left to right. In each of n lines print the index of the domino to put in the corresponding position and then, after a space, character "+" (if you don't need to turn the domino) or "–" (if you need to turn it).
5 1 2 2 4 2 4 6 4 2 1
2 - 1 - 5 - 3 + 4 -
解析
图论,欧拉路径。
讲解参见《算法竞赛入门经典(第二版)》P169
下面的程序同时适用于欧拉路径和欧拉回路
void euler(int u)
{
for(int v=0;v<N;v++)
if(map[u][v] && !vis[u][v])
{
vis[u][v]=vis[v][u]=1;
euler(v);
ans.push((edge){u,v});
}
}
找到的路径是逆序的,因此ans是栈。dfs的时候进栈,输出的时候出栈。
另外对于有多块连通块的情况,可以判断ans.size()是不是等于边数。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct Edge
{
int v;
char c;
}edge[220];
vector<Edge> ans;
vector<int> Chain[10];
int N;
bool flag[110];
void dfs(int x)
{
for(int i=0;i<Chain[x].size();i++)
{
int v=edge[Chain[x][i]].v,id=Chain[x][i]>>1;
if(!flag[id])
{
flag[id]=1;
dfs(v);
ans.push_back((Edge){id,edge[Chain[x][i]].c});
}
}
}
void print()
{
for(int i=N-1;i>=0;i--)
printf("%d %c\n",ans[i].v+1,ans[i].c);
}
int main()
{
//readdata
scanf("%d",&N);
for(int i=0;i<N;i++)
{
int a,b; scanf("%d%d",&a,&b);
edge[2*i]=(Edge){b,'+'}; Chain[a].push_back(2*i);
edge[2*i+1]=(Edge){a,'-'}; Chain[b].push_back(2*i+1);
}
//existance
int u=edge[0].v,sum=0;
for(int i=0;i<=6;i++)
if(1&Chain[i].size()) u=i,sum++;
//print answer
if(sum==0 || sum==2)
{
dfs(u);//find answer
if(ans.size()==N) print();
else printf("No solution");
}
else printf("No solution");
//while(1);
return 0;
}