hdu 3018 欧拉路定理+并查集
来源:互联网 发布:网游数据库 编辑:程序博客网 时间:2024/06/03 04:48
题目:hdu 3018
题意:
有一些道路,每次只能走一遍,问最少几次走遍所有道路?
分析:
这题是经典问题:一笔画问题。解决这个问题,需要知道几个定理和定义:
1. 欧拉道路:能否从无向图中的一个节点出发走出一条道路,每条边恰好经过一次,这样的路线称为欧拉道路。
2. 如果一个图是联通的且最多只有两个奇度点,则一定存在欧拉道路。如果有两个奇度点,则必须从其中一个出发,回到另一个终止。如果没有奇度点,可以从任一点出发。
3. 对于有向图,如果想构成欧拉路,那么:最多只能有两个点的入读不等于出度,而且必须是其中一个点的出度比入度大一,另一个点的入度比出度大一。
对于这题:先用并查集找出连通图,然后再找出每个连通块中奇度点的个数,如果没有奇度点,那么只需要一笔,如果有奇度点,那么需要奇点的个数/2笔。另外,这题独立点需要忽略掉。
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;typedef long long ll;const int N=100000+5;int fa[N];int findfa(int x){return x==fa[x]?x:fa[x]=findfa(fa[x]);}int de[N],cnt[N],vis[N];int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++)fa[i]=i; memset(de,0,sizeof(de)); memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); int u,v; for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); de[u]++;de[v]++; int x=findfa(u),y=findfa(v); if(x!=y)fa[x]=y; } vector<int>ans; for(int i=1;i<=n;i++){ int x=findfa(i); if(!vis[x]){ vis[x]=1; ans.push_back(x); } if(de[i]&1){ cnt[x]++; } } int sum=0; for(int i=0;i<ans.size();i++){ int x=ans[i]; if(de[x]==0)continue; //独立点忽略掉 if(cnt[x]==0)sum++; else sum+=cnt[x]/2; } printf("%d\n",sum); } return 0;}
0 0
- hdu 3018 欧拉路定理+并查集
- hdu 3018(欧拉路+并查集)
- HDU 3018 Ant Trip【欧拉路、并查集】
- HDU 3018 Ant Trip 欧拉路 并查集
- hdu 3018 欧拉图+并查集
- hdu 1116 欧拉路 + 并查集
- HDU 3371 并查集
- HDU 2473 并查集
- hdu 1116 并查集
- HDU 1856 并查集
- HDU 1598 并查集
- HDU-1232 并查集
- 【并查集】hdu 2818
- hdu 1232 并查集
- hdu 1856(并查集)
- HDU 1598 并查集
- HDU-1232(并查集)
- hdu 1856 并查集
- oracle函数索引
- strcmp函数的实现方法
- 表单提交返回json 弹出下载框
- 云计算时代的到来
- linux 知识体系精炼版
- hdu 3018 欧拉路定理+并查集
- hive大数据倾斜总结
- Deep learning:(龙星计划2013深度学习课程小总结)
- 汉诺塔递归问题
- 《笑傲江湖曲》所感
- CocoaPods安装和使用教程
- problemG
- 详解 Redis 应用场景及应用实例
- c/c++ 高位扩展的坑