POJ 1041 求解欧拉回路方案

这题模板太神了……几乎不用自己再写什么,只要把图建好就行了……

对了,刚才做了后琦神说了欧拉回路了汉密顿回路才记得其区别:欧拉回路是一笔画问题,即边走且只走一次;而汉密顿回路是点走且只下次一次。

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <list>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define sc(a,b) scanf("%d%d",&a,&b)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 1000005
#define MN 2000
#define INF 1000000009
#define eps 1e-7
using namespace std;
typedef long long ll;
int f[MN];
vector<int>path;
vector< pair<int,int> >adj[MN];
bool vis[MM];
int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}
void add(int x,int y,int z)
{
    adj[x].push_back(make_pair(z,y));
    adj[y].push_back(make_pair(z,x));
}
void dfs(int u)
{
    for(int i=0; i<adj[u].size(); i++)
        if(!vis[adj[u][i].first])
        {
            vis[adj[u][i].first]=true;
            dfs(adj[u][i].second);
            path.push_back(adj[u][i].first);
        }
}
bool eluer()
{
    int i,j,origin=-1;
    for(i=0; i<MN; i++) f[i]=i;
    for(i=0; i<MN; i++)
        for(j=0; j<adj[i].size(); j++)
            f[find(i)]=find(adj[i][j].second);
    for(i=0; i<MN; i++)
        if(adj[i].size())
        {
            if(adj[i].size()%2==1) return false;
            if(origin==-1) origin=i;
            if(find(i)!=find(origin)) return false;
            sort(adj[i].begin(),adj[i].end());
        }
    path.clear();
    mem(vis,false);
    if(origin!=-1) dfs(origin);
    reverse(path.begin(),path.end());
    return true;
}
int main()
{
    int x,y,z,i,len;
    while(sc(x,y)&&(x||y))
    {
        for(i=0;i<MN;i++) adj[i].clear();
        sca(z),add(x,y,z);
        while(sc(x,y)&&(x||y))
            sca(z),add(x,y,z);
        if(eluer())
        {
            len=path.size();
            for(i=0;i<len;i++)
                printf("%d%c",path[i],i!=len-1?' ':'\n');
        }
        else puts("Round trip does not exist.");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值