SGU101 Domino

1920 ワード

N(N<=100)枚の骨牌は、それぞれの骨牌の両端に0-6の数字がある.前の骨牌の右端と後ろの骨牌の左端の数字が同じになるように、直線につなげてもらえますか.骨牌の左右両端の数字を回転させることで交換できる.
オラ回路、オラ回路の存在の判定:
1、オラロード:
無方向図:連通.度が奇数の頂点の数は0または2です.
有向図:ベース図が連通している.すべての頂点の入度は、出度に等しいか、1つの頂点のみが入度-出度=1であり、1つの頂点のみが出度-入度=1である.
2、オラ回路:
無方向図:連通.度が奇数の頂点の数は0です.
有向図:ベース図が連通している.すべての頂点の入度は出度に等しい.
この問題は無方向図求欧拉路に属する.
#include<stdio.h>
#include<vector>
#include<cstring>
using namespace std;
struct Edge
{
    int u,v;
    bool vis;
};
Edge edge[105];
int deg[7];
vector<pair<int,char> >ans;
vector<int> a[7];

void dfs(int u)
{
    int i,j;
    for(i=0;i<a[u].size();++i)
    {
        j=a[u][i];
        if(!edge[j].vis)
        {
            edge[j].vis=1;
            if(edge[j].u==u)
            {
                dfs(edge[j].v);
                ans.push_back(make_pair(j+1,'+'));
            }
            else
            {
                dfs(edge[j].u);
                ans.push_back(make_pair(j+1,'-'));
            }
        }
    }
}
int main()
{
    int i,n;
    scanf("%d",&n);
    memset(deg,0,sizeof(deg));
    for(i=0;i<n;++i)
    {
        scanf("%d%d",&edge[i].u,&edge[i].v);
        edge[i].vis=0;
        deg[edge[i].u]++,deg[edge[i].v]++;
        a[edge[i].u].push_back(i);
        a[edge[i].v].push_back(i);
    }
    int s=0,start;
    for(i=0;i<7;++i) if(deg[i]&1) {start=i;++s;}  //       
    if(s==0||s==2)
    {
        ans.clear();
        for(i=0;i<7;++i)
            if(deg[i]) start=i;
        for(i=0;i<7;++i)
            if(deg[i]&1) start=i;
        dfs(start);
        if(ans.size()<n) puts("No solution");
        else
        {
            for(i=ans.size()-1;i>=0;--i) printf("%d %c
",ans[i].first,ans[i].second); } } else puts("No solution"); return 0; }