hihoCoder#1181(欧拉路径)

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌。

主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过。

小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着:

将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙。切记骨牌需要数字相同才能连接。
——By 无名的冒险者

小Hi和小Ho打开了主角的道具栏,发现主角恰好拥有M快骨牌。

小Ho:也就是说要把所有骨牌都放在凹槽中才能关闭火焰墙,数字相同是什么意思?

小Hi:你看,每一块骨牌两端各有一个数字,大概是只有当数字相同时才可以相连放置,比如:

小Ho:原来如此,那么我们先看看能不能把所有的骨牌连接起来吧。

提示:Fleury算法求欧拉路径

输入

第1行:2个正整数,N,M。分别表示骨牌上出现的最大数字和骨牌数量。1≤N≤1,000,1≤M≤5,000

第2..M+1行:每行2个整数,u,v。第i+1行表示第i块骨牌两端的数字(u,v),1≤u,v≤N

输出

第1行:m+1个数字,表示骨牌首尾相连后的数字

比如骨牌连接的状态为(1,5)(5,3)(3,2)(2,4)(4,3),则输出"1 5 3 2 4 3"

你可以输出任意一组合法的解。

样例输入
5 5
3 5
3 2
4 2
3 4
5 1
样例输出
1 5 3 4 2 3注意:此题目必须从1号结点开始遍历才能AC.无向图删边的时候要将与u,v相关联的有向边同时删除。无向图求欧拉路径用代码1方便,有向图求欧拉路径利用前向星方便。
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int MAXN=1005;
struct Edge{
    int u,v;
    int getTo(int u)
    {
        if(u==this->u)    return v;
        else return this->u;
    }
}es[5005];
int n,m;
int deg[MAXN],vis[5005];
int path[5005],top;
vector<int> arc[MAXN];
void dfs(int u)
{
    for(int i=0,size=arc[u].size();i<size;i++)
    {
        int id=arc[u][i];
        if(!vis[id])
        {
            vis[id]=1;
            int v=es[id].getTo(u);
            dfs(v);
        }
    }
    path[top++]=u;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(deg,0,sizeof(deg));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            arc[i].clear();
        }
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            es[i].u=u;
            es[i].v=v;
            arc[u].push_back(i);
            arc[v].push_back(i);
            deg[u]++;
            deg[v]++;
        }
        /* WA??
        for(int i=1;i<=n;i++)
        {
            if(deg[i]%2==1)
            {
                dfs(i);
                break;
            }
        }
        */
        dfs(1);
        for(int i=0;i<top-1;i++)
        {
            printf("%d ",path[i]);
        }
        printf("%d\n",path[top-1]);
    }
    return 0;
}

前向星实现.

#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1005;
struct Edge{
    int to,net;
    bool tag;
}es[MAXN*10];
int n,m;
int head[MAXN],tot;
int path[5005],top;
int deg[MAXN];
void addedge(int u,int v)
{
    es[tot].to=v;
    es[tot].tag=false;
    es[tot].net=head[u];
    head[u]=tot++;
}
void dfs(int u)
{
    for(int i=head[u];i!=-1;i=es[i].net)
    {
        if(!es[i].tag)
        {
            int v=es[i].to;
            for(int j=head[v];j!=-1;j=es[j].net)
            {
                if(es[j].to==u&&!es[j].tag)
                {
                    es[j].tag=true;
                    break;
                }
            }
            es[i].tag=true;
            dfs(v);
        }
    }
    path[top++]=u;
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
        deg[u]++;
        deg[v]++;
    }
    /* Wrong
    for(int i=1;i<=n;i++)
    {
        if(deg[i]%2==1)
        {
            dfs(i);
            break;
        }
    }
    */
    dfs(1);//Accepted
    for(int i=0;i<top-1;i++)
    {
        printf("%d ",path[i]);
    }
    printf("%d\n",path[top-1]);
    return 0;
}

时间: 2024-07-31 02:57:13

hihoCoder#1181(欧拉路径)的相关文章

hihoCoder - 1181 - 欧拉路&#183;二 (Fleury算法求欧拉路径)

#1181 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过. 小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. --By 无名的冒险者 小Hi和小Ho打开了主角的道具栏,发现

hihocoder 1181 欧拉路.二

传送门:欧拉路·二 #1181 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌.主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过.小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. ——By 无名的冒险者 小Hi和小Ho打开了主

hihoCoder #1181: 欧拉路&#183;二 (麻烦)

题意:提供一个图,要求找出欧拉路的路径(任意合法的路径均可,保证图肯定有欧拉路). 思路:深搜的过程中删除遍历过的边,并在回溯时打印出来.在深搜时会形成多个环路,每个环都有一个或多个结点与其他环相扣,这样就可以产生欧拉路. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1005; 4 int n, m, a, b; 5 vector< vector<int> > vect;//邻接表 6

【hihocoder】欧拉路径 并查集判连通

#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; int n,m; const int maxn=1e4+2; const int maxm=5e4+2; int degree[maxn

【欧拉回路】【欧拉路径】【Fleury算法】CDOJ1634 记得小苹初见,两重心字罗衣

Fleury算法看这里 http://hihocoder.com/problemset/problem/1181 把每个点看成边,每个横纵坐标看成一个点,得到一个无向图. 如果新图中每个点的度都是偶数,那么就是一个欧拉图,对该图跑一遍欧拉回路,对走过的边轮流染色,就可以保证每个点所连的边的红蓝颜色相等. 如果存在度数为奇数的点,新建两个点a和b.把横坐标的度数为奇数的点和a连边,把纵坐标为奇数的点和b连边,这样最多只有a和b的度数为奇数,可以跑欧拉路径. 注意Fleury算法的时候,要及时把访问

hihocoder 1176

hihocoder 1176 题意:N,M.分别表示岛屿数量和木桥数量,一笔画 分析:欧拉路问题(给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路) 欧拉路的条件 一个无向图存在欧拉路当且仅当该图是连通 且只有2个点的度数是奇数(此时这两个点只能作为欧拉路径的起点和终点 用并查集判断第一个条件 第二个直接用数组存 1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #i

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一

变形课(DFS hdu 1181)

变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 19133    Accepted Submission(s): 6892 Problem Description 呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu