例题5.3 项链 UVa10054

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("");
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值