1.题目描述:点击打开链接
2.解题思路:本题利用欧拉回路解决。根据题意,显然我们需要找到一条路径,使得前一个路径的结点和当前路径的结点颜色值相同,因此自然想到用欧拉回路来判断。不过在求解欧拉回路之前可以做一个预处理:即检查所有端点的度数是否为偶数,如果不是,那么一定无解。如果发现最终找到的边数不等于n,或者第一条边的起始点和最后一条边终点颜色值不等,说明无解。
3.代码:
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<list>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int,int> P;
const int maxcolor=50+5;
int n;
int g[maxcolor][maxcolor];
int deg[maxcolor];
struct Edge
{
int from,to;
Edge(int x,int y):from(x),to(y){}
};
vector<Edge>ans;
void euler(int u)
{
for(int v=1;v<maxcolor;v++)
if(g[u][v])
{
g[u][v]--;g[v][u]--;
euler(v);
ans.push_back(Edge(u,v));
}
}
int main()
{
int T;
scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
scanf("%d",&n);
me(g);me(deg);
int start=-1;
for(int i=0;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
g[u][v]++;g[v][u]++;
deg[u]++;deg[v]++;
start=u;
}
bool solved=true;
for(int i=1;i<maxcolor;i++)
if(deg[i]&1){solved=false;break;}
if(solved)
{
ans.clear();
euler(start);
if(ans.size()!=n||ans[0].to!=ans[ans.size()-1].from)
solved=false;
}
printf("Case #%d\n",kase);
if(!solved)puts("some beads may be lost");
else for(int i=ans.size()-1;i>=0;i--)
printf("%d %d\n",ans[i].from,ans[i].to);
if(kase<T)puts("");
}
}