#include<bits/stdc++.h>
using namespace std;
int n,m;
int x,y;
int num,cnt;
int degree[100007],vis[100007],viss[400040],first[100007];
vector<int>jidian,road[100007];
struct node
{
    int v,next;
}xu[400040];
void init()//初始化
{
    num=0,cnt=1;
    memset(degree,0,sizeof(degree));
    memset(vis,0,sizeof(vis));
    memset(viss,0,sizeof(viss));
    memset(first,-1,sizeof(first));
    jidian.clear();
}
void add_edge(int u,int v)//将点联接
{
   xu[++cnt].v=v;
   xu[cnt].next=first[u];
   first[u]=cnt;
}
void dfs(int u)//寻找度数为奇数的点
{
    vis[u]=1;
    if(degree[u]&1)
        jidian.push_back(u);
    for(int i=first[u];i!=-1;i=xu[i].next)
    {
        int v=xu[i].v;
        if(!vis[v])
            dfs(v);
    }
}
void dfss(int u)//将要走的点存进向量,绘制路线
{
    for(int i=first[u];i!=-1;i=xu[i].next)
    {
        if(!viss[i])
        {
            viss[i]=viss[i^1]=1;//与1异或可以得到相邻的点,如:(1,2),(3,4)等
            int v=xu[i].v;
            dfss(v);
            if(i>2*m+1)//该点为奇点
            {
                num++;//增加一笔
            }
            else
            {
                int jiedian=i&1?(i/2):((-1)*(i/2));//如果是偶数的话,当时建边是是反向边
                road[num].push_back(jiedian);
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add_edge(x,y);//建边
            add_edge(y,x);
            degree[x]++;//记录节点度数
            degree[y]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&degree[i])//没有被访问过并且不是孤立的节点
            {
                dfs(i);
                int siz=jidian.size();//度数为奇数的数量
                for(int j=2;j<siz;j+=2)//跳过欧拉回路中至少存在的两个奇点
                {
                    add_edge(jidian[j],jidian[j+1]);
                    add_edge(jidian[j+1],jidian[j]);
                }
                num++;
                if(jidian.size())
                    dfss(jidian[0]);//从多余的奇点出发
                else
                    dfss(i);//否则就从随意一个点出发
                jidian.clear();
            }
        }
        printf("%d\n",num);
        for(int i=1;i<=num;i++)
        {
            int sizz=road[i].size();
            printf("%d ",sizz);
            for(int j=0;j<sizz-1;j++)
            {
                printf("%d ",road[i][j]);
            }
            printf("%d\n",road[i][sizz-1]);
            road[i].clear();
        }
    }
    return 0;
}
/*欧拉图:图中只有两个度数为奇数的点,或者所有点的度数均为偶数,
这样我们只要选择一个度数为奇数的点作为起点跑一遍欧拉回路同时记录路径即可
(如果所有点的度数都是偶数的话就选任意一个点就行了),
我们dfs求完欧拉路径,然后遇到虚边,num++,
放入另外的一个队列中(相当于上图右边切断虚边,变成了两段,最后输出所有路径方案*/

2018杭电多校第二场1003(DFS,欧拉回路)的更多相关文章

  1. hdu6312 2018杭电多校第二场 1004 D Game 博弈

    Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. 2018 Multi-University Training Contest 2 杭电多校第二场

    开始逐渐习惯被多校虐orz  菜是原罪 1004  Game    (hdoj 6312) 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6312 虽然披着 ...

  3. 杭电多校第二场 hdu 6315 Naive Operations 线段树变形

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...

  4. 2019杭电多校第二场hdu6601 Keen On Everything But Triangle

    Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...

  5. 2019杭电多校第二场hdu6602 Longest Subarray(线段树)

    Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...

  6. 杭电多校第二场 1005 hack it

    题意: 构造一个n*n 的 01 矩阵, 0 < n < 2001,  矩阵需要满足没有一个子矩阵的4个角都是1,并且矩阵内1的个数至少有85000个. 题解:数论构造题 参考From 代 ...

  7. 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)

    题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...

  8. 2019年杭电多校第二场 1012题Longest Subarray(HDU6602+线段树)

    题目链接 传送门 题意 要你找一个最长的区间使得区间内每一个数出现次数都大于等于\(K\). 思路 我们通过固定右端点考虑每个左端点的情况. 首先对于每个位置,我们用线段树来维护它作为\(C\)种元素 ...

  9. 2019年杭电多校第二场 1002题Beauty Of Unimodal Sequence(LIS+单调栈)

    题目链接 传送门 思路 首先我们对\(a\)正反各跑一边\(LIS\),记录每个位置在前一半的\(LIS\)中应该放的位置\(ans1[i]\),后一半的位置\(ans2[i]\). 对于字典序最小的 ...

随机推荐

  1. 恢复delete删除的数据

    SELECT * FROM tablename AS OF TIMESTAMP TO_TIMESTAMP('2010-12-15 11:10:17', 'YYYY-MM-DD HH:MI:SS')

  2. 常见ETL工具一览,你知多少?

    这些年,几乎都与ETL打交道,接触过多种ETL工具.现将这些工具做个整理,与大家分享. 一 ETL工具[国外] 1. datastage点评:最专业的ETL工具,价格不菲,使用难度一般 下载地址:ft ...

  3. java:Map借口及其子类HashMap五,identityHashMap子类

    java:Map借口及其子类HashMap五,identityHashMap子类 了解:identityHashMap子类 一般情况下,标准的Map,是不会有重复的key值得value的,相同的key ...

  4. 分析CSS布局中BFC

    1.什么是BFC BFC(Block Formatting Context,块级元素格式化上下文)是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和 ...

  5. Java_基础_01_static和final

    二.参考资料 1.java入门之关键字static和final 2.static和final的区别

  6. javaScript-进阶篇(一)

    1.变量 1.必须以字母.下划线或美元符号开头,后面可以跟字母.下划线.美元符号和数字. 2.变量名区分大小写,如:A与a是两个不同变量. 3.不允许使用JavaScript关键字和保留字做变量名. ...

  7. linux命令学习笔记(55):traceroute命令

    通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包 由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不 ...

  8. 【二叉树的递归】03判断二叉树中有没有和为给定值的路径【Path Sum】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树和一个和,判断这个树 ...

  9. JS性能之setTimeout与clearTimeout

    测试环境: chrome浏览器 结论: 1 一个页面用setTimeout越多,该页面消耗的内存就会越多,几乎成正比. 2 在'startCount(1000000);-->100万'情况下,不 ...

  10. SQL SERVER 中的*=和=*

    一.* =和= * 是在sql server2000中左连接,右连接的用法相当于left join 和right join,现在sql2005和2008默认是不支持的,可以设置兼容2000或2008 ...