http://acm.hdu.edu.cn/showproblem.php?pid=3018

题意  ——许多蚂蚁 遍历一个图 每一条边只能走一次  问至少要把这些蚂蚁分为几群

说白了就是 至少几笔可以画出一个特定的 图 出来

*********************************************

欧拉回路:图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次,

称这条回路为欧拉回路。具有欧拉回路的图成为欧拉图。

判断欧拉路是否存在的方法

有向图:图连通,有一个顶点出度大入度1,有一个顶点入度大出度1,其余都是出度=入度。

无向图:图连通,只有两个顶点是奇数度,其余都是偶数度的。

判断欧拉回路是否存在的方法

有向图:图连通,所有的顶点出度=入度。

无向图:图连通,所有顶点都是偶数度。

*******************************************

先找出有几个 连通分支 再看连通分支中有几个 点的度数为奇数 要是奇度数为0 则加count++   否则count+=奇度数、2;

我没有用并查集 而是dfs一遍 找出有几个连通分支并记录下每个点 所属的连通分支序号

有个要注意的地方是 他只是遍历边 要是有的点是孤立的是 不用管的 (我一开始没注意到这里 孤立的点也加上了结果 wa了好久都硬是找不到错误的地方 = =  )

我的代码:

#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
vector <int> G[100002];int c,vis[100002],du[100002],ans[100002],p[100002];   //  1到c   p[i]: 第i个连通分支的 奇度数void dfs(int n)
{vis[n]=1;int len;ans[n]=c;len=G[n].size();            //i 点的连通分量的编号为ans[i]for(int i=0;i<len;i++)if(vis[G[n][i]]==0)dfs(G[n][i]);
}
int main()
{int i,j,n,m,s,e,temp=0;while(scanf("%d%d",&n,&m)!=EOF){for(i=0;i<=temp;i++)G[i].clear();temp=n;c=0;memset(vis,0,sizeof(vis));memset(du,0,sizeof(du));memset(p,0,sizeof(p));while(m--){            scanf("%d%d",&s,&e);du[s]++;  du[e]++;G[s].push_back(e);G[e].push_back(s);            // 图}for(i=1;i<=n;i++){if(vis[i]==0){c++;dfs(i);}}for(i=1;i<=n;i++)if(du[i]%2==1)p[ans[i]]++;int final=0;for(i=1;i<=n;i++){if(du[i]==0)continue;              //孤立的点 忽略if(p[ans[i]]!=-1)    //该店所处的连通分支 已经加过{            if(p[ans[i]]==0)final++;else                     final+=p[ans[i]]/2;                p[ans[i]]=-1;          //标记}}printf("%d\n",final);}return 0;
}

黄霖的:(他用了并查集)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int f[100003];
int visit[1000003];
int num[100003];
void ini(int n)
{int i;for(i=1;i<=n;i++){f[i]=i;visit[i]=0;num[i]=0;}
}
int find(int x)
{int r,i=x;while(x!=f[x])x=f[x];while(i!=x){r=f[i];f[i]=x;i=r;}return x;
}
void Union(int x,int y)
{visit[x]++;visit[y]++;x=find(x);y=find(y);if(x==y)return ;else {f[x]=y;}
}
int main()
{int n,m,i,k,sum,x,y;while(scanf("%d%d",&n,&m)>0){ini(n);for(i=1;i<=m;i++){scanf("%d%d",&x,&y);Union(x,y);}for(i=1;i<=n;i++)find(i);for(i=1;i<=n;i++){if(visit[i]%2==1){k=f[i];num[k]++;}}sum=0;for(i=1;i<=n;i++){if(visit[i]>0 && f[i]==i){if(num[i]==0)sum++;else if(num[i]>0)sum=sum+num[i]/2;}}printf("%d\n",sum);}return 0;
}

网上另外一个人的   (他的并查集  我没看懂,谁看懂了的  指点一下)

#include <iostream>
#include <stdio.h>
using namespace std;
const int maxv = 100000 + 2;
int odds[maxv]; /* 顶点 */
int du[maxv]; /* 每个顶点的度数 */
int p[maxv]; /* 并查集数组 */
bool used[maxv];
int scc[maxv]; /* scc个数 */
void init(int n)
{for(int i = 0; i <= n; ++i){odds[i] = 0;p[i] = -1;du[i] = 0;used[i] = 0;}
}
int utf_find(int x)
{if(0 <= p[x]){p[x] = utf_find(p[x]);return p[x];}return x;
}
void utf_union(int a, int b)
{int r1 = utf_find(a);int r2 = utf_find(b);if(r1 == r2)return;int n1 = p[r1];int n2 = p[r2];if(n1 < n2){p[r2] = r1;p[r1] += n2;}else{p[r1] = r2;p[r2] += n1;}
}
int main()
{int n = 0;int m = 0;int a = 0;int b = 0;int i = 0;int cnt = 0;while(scanf("%d%d", &n, &m) != EOF){init(n);cnt = 0;for(i = 1; i <= m; ++i){scanf("%d%d", &a, &b);du[a]++;du[b]++;utf_union(a, b);}for(i = 1; i <= n; ++i){int f = utf_find(i);if(!used[f]){used[f] = 1;scc[cnt++] = f;}if(1 == du[i]%2)odds[f]++;}int ret = 0;for(i = 0; i < cnt; ++i){if(0 == du[scc[i]])continue;if(0 == odds[scc[i]])++ret;elseret += odds[scc[i]]/2;}printf("%d\n", ret); }return 0;
}

转载于:https://www.cnblogs.com/assult/archive/2013/06/09/3130114.html

hdu 3018 图 欧拉回路 并查集相关推荐

  1. I - Ant Trip (无向图欧拉回路+并查集),判断

    I - Ant Trip 参考博客:Ant Trip(欧拉回路+并查集) 参考:欧拉路径问题与欧拉回路问题 题意:给你无向图的 N 个点和 M 条边,保证这 M 条边都不同且不会存在同一点的自环边,现 ...

  2. CF990G GCD Counting(树上莫比乌斯反演,分层图,并查集)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Problem 给定一棵点带权无根树,对于每个 k∈[1,2×105]k\in[1,2\times10 ...

  3. hdu 1116 欧拉回路 并查集 一组字符串能否首尾相连成一个字符串

    主要是欧拉回路的基础知识,用并查集加工处理 注意欧拉回路和并查集的细节判断 不能粘贴复制,一定要理解之后再敲一遍代码,否则浪费更多的时间 #include <stdio.h> #inclu ...

  4. UVA - 10129 Play on Words(欧拉回路+并查集)

    2.解题思路:本题利用欧拉回路存在条件解决.可以将所有的单词看做边,26个字母看做端点,那么本题其实就是问是否存在一条路径,可以到达所有出现过的字符端点.由于本题还要求了两个单词拼在一起的条件是前一个 ...

  5. 牛客小白月赛2 D. 虚虚实实(欧拉回路,并查集)

    题目描述 震为雷,临危不乱,亨通畅达:巽为风,柔顺伸展,厚载万物. 震卦:洊雷,震,君子以恐惧修省.一口金钟在淤泥,人人拿着当玩石,忽然一日钟悬起,响亮一声天下知. 巽卦:随风,巽,君子以申命行事.一 ...

  6. HDU 2473 Junk-Mail Filter(并查集的删除操作)

    题目地址:HDU 2473 这题曾经碰到过,没做出来. .如今又做了做,还是没做出来. ... 这题涉及到并查集的删除操作.想到了设一个虚节点,可是我把虚节点设为了要删除的点的父节点.一直是栈溢出,目 ...

  7. 【畅通工程 HDU - 1232 】【并查集模板题】

    并查集讲解和模板 有一个博文对此分析的很透彻,附链接 为避免原链接失效,现摘录如下: 为了解释并查集的原理,我将举一个更有爱的例子. 话说江湖上散落着各式各样的大侠,有上千个之多.他们没有什么正当职业 ...

  8. HDU 4775 Infinite Go 并查集

    题目链接:Infinite Go Infinite Go Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  9. hdu 1811(拓扑排序+并查集)

    解题思路: 拓扑排序的两个性质: ①如果一次入队入度为零的点大于1则说明拓扑排序序列不唯一 ②如果排序的总个数小于给定的个数,则说明存在回路 可以先把"="的两个数用并查集放在一个 ...

最新文章

  1. Python学习--not语句
  2. 决策树算法(二)——构建数据集
  3. 链接静态库时__imp_前缀错误
  4. express 解析 ajax post 数据 body 为空对象
  5. 电脑编程python老是出现错误_python常见的编程错误
  6. Python 的 eval() 与 exec()区别
  7. 【转】图形学基础之透视校正插值
  8. 火山引擎端云一体化服务:打造面向体验的视频云
  9. console程序也有版本和图标
  10. (五)python3 只需3小时带你轻松入门—— 逻辑运算符
  11. android switch 未定义,在switch语句中初始化时未定义的变量?
  12. 天地图专题一:加载天地图
  13. IDC:大数据——数字化转型时代的大商机
  14. 【sklearn第五讲】特征提取(上)
  15. jquery中的尺寸函数width(),height(),innerWidth(),outerWidth()等的用法
  16. 安装并使用达梦数据库
  17. 蒙特卡罗 Monte Carlo 模拟
  18. 很多人生哲理好句子分享
  19. ylbtech-DBD-WeShop(微店)
  20. phpcms v9摆脱手机门户,轻松搭建wap手机站

热门文章

  1. [MacOSX]_[LaunchDaemons]_[Mac OS X 安装Tomcat开机启动服务的方法之一]
  2. 【大白话学习】UniApp 微信小程序与APP应用 开发零基础入门教程(一)---基础页面框架搭建
  3. pygame学习笔记——检测鼠标碰到、点击图片
  4. 网站漏洞整改报告公司之攻防方案
  5. Harris角点检测及数据分析
  6. uos操作系统安装mysql
  7. SQL 查询的分布式执行与调度
  8. 01_测试基础知识---微信公众号测试点
  9. windows使用模拟器
  10. 荣耀手机鸿蒙系统手机,4部荣耀手机可升为鸿蒙系统,有你的手机吗?花粉的春天来了!...