题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=101
思路: 最裸的欧拉路的题目 把骨牌的每一面当成点 每一张骨牌的两面都建一条无向边 求出此图的一条欧拉路即可。
在此总结一下欧拉路的知识:
无向图的欧拉路的存在判定: 为连通图 度数为奇数的点的个数为0 or 2
欧拉路的输出:
1.度数为奇数的点的个数为0(此图存在欧拉回路) 任选一点 用dfs入栈记录 最后再倒着输出即可
2.度数为奇数的点的个数为2(非欧拉图) 选出度数为奇数的点 然后再进行dfs
代码中并查集的判联通部分可以用dfs代替
code:
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=10500;
const int maxe=10500;
struct edge
{
int to,next,flag;
} G[maxe];
int head[maxn],si,du[maxn],way[maxe];
int cnt,nn;
bool vis[10];
void add_edge(int s,int t)
{
G[si].flag=true;
G[si].to=t;
G[si].next=head[s];
head[s]=si++;
G[si].flag=true;
G[si].to=s;
G[si].next=head[t];
head[t]=si++;
}
int par[maxn],num[maxn];
void init(int n_)
{
for(int i=0;i<=n_;i++){
par[i]=i;
num[i]=1;
}
}
int Find(int x)
{
if(x==par[x]) return x;
return par[x]=Find(par[x]);
}
void unite(int x,int y)
{
x=Find(x);
y=Find(y);
if(num[x]<num[y]){
par[x]=y;
num[y]+=num[x];
}
else{
par[y]=x;
num[x]+=num[y];
}
}
bool same(int x,int y)
{
return Find(x)==Find(y);
}
void dfs(int vv,int tt)
{
for(int i=head[vv];i!=-1;i=G[i].next){
if(!G[i].flag) continue;
G[i].flag=G[i^1].flag=false;
dfs(G[i].to,i);
}
if(tt!=-1) way[cnt++]=tt;
}
void output(int kk)
{
cnt=0;
if(kk==0){
for(int i=0;i<=6;i++){
if(!vis[i]) continue;
dfs(i,-1);
break;
}
}
else{
for(int i=0;i<=6;i++){
if(!vis[i]) continue;
if(du[i]%2!=0){
dfs(i,-1);
break;
}
}
}
for(int i=cnt-1;i>=0;i--){
if(way[i]%2) printf("%d -\n",way[i]/2+1);
else printf("%d +\n",way[i]/2+1);
}
}
int main()
{
int N,s,t,cnt1,cnt2,nn;
bool mark;
while(scanf("%d",&N)!=EOF){
init(N);
nn=0;
memset(vis,0,sizeof(vis));
memset(du,0,sizeof(du));
memset(head,-1,sizeof(head));
si=0;
for(int kk=0;kk<N;kk++){
scanf("%d%d",&s,&t);
add_edge(s,t);
du[s]++;
du[t]++;
if(!same(s,t)) unite(s,t);
vis[s]=vis[t]=true;
}
for(int i=0;i<=6;i++) if(vis[i]) nn++;
mark=0;
for(int i=0;i<=6;i++){
if(!vis[i]) continue;
if(num[Find(i)]!=nn){
printf("No solution\n");
mark=1;
}
break;
}
if(mark==1) continue;
cnt1=cnt2=0;
for(int i=0;i<=6;i++){
if(!vis[i]) continue;
if(du[i]%2==0) cnt1++;
else cnt2++;
}
if(cnt2==0) output(0);
else if(cnt2==2) output(1);
else printf("No solution\n");
}
}