HDU 3018 Ant Trip
2014-10-15 16:51
316 查看
这个题目一开始看起来,感觉有点难,请原谅我水平低,呵呵。因为做这题时是欧拉回路专题,所以肯定用欧拉回路,于是自己就在想怎么才能用欧拉回路呢?一开始想用DFS搜索,一看不行,太麻烦,本来自己就懒,所以这招几秒钟之后就排除在外。于是就简单的画了几个节点的图,来寻找其中的关系。经过一些试验,我发现貌似所要走的次数只和图中度为奇数的结点的个数number有关。一开始我还对number分奇偶性讨论,可是后来发现没必要。整体思路出来之后就开始写。写完去提交,WA,呵呵,意料之中。于是又开始了悲催的找错误的历程。找寻了好久才发现,原来错在了并查集上,看来自己还是要对并查集更深入地理解理解一番了,呵呵。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N=100005; int degree ,father ,deep ,number ; int m,n;
//这里自己的并查集写的可能有所复杂了,例如deep数组可能就没必要开,对时间影响并不大,
//我看了别人写的,貌似很简单,不过并查集就这几个操作,我就当写写练练手吧。 void make_set() { for(int i=1;i<=n;i++) { father[i]=i; deep[i]=0; number[i]=0; } } int find_father(int x) { if(x!=father[x]) father[x]=find_father(father[x]); return father[x]; } void merge(int x,int y) { int a=find_father(x); int b=find_father(y); if(a==b) return; if(deep[a]>deep[b]) father[b]=a; else { if(deep[a]==deep[b]) deep[b]++; father[a]=b; } } int main() { int a,b; while(scanf("%d%d",&n,&m)!=EOF) { memset(degree,0,sizeof(degree)); make_set(); while(m--) { scanf("%d%d",&a,&b); degree[a]++,degree[b]++; merge(a,b); } vector<int> v; for(int i=1;i<=n;i++) {
//我就是坑在这句话上的,一开始自己是这样的:f=father[i],我想前面的并查集之后,
//i的父亲肯定是树的根结点,没想到真的错了,打错特错,害得我找了好久的错误,
//以后自己要当心了,呵呵! int f=find_father(i); if(f==i&°ree[i]!=0) v.push_back(i); if(degree[i]%2==1) number[f]++; } int ans=0,len=v.size();
//这里要注意如果是欧拉环路的情况,这样ans直接加1就可以了 for(int i=0;i<len;i++) { int t=v.at(i); if(number[t]==0) ans++; else ans+=number[t]/2; } v.clear(); printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 3018 Ant Trip
- hdu 3018 Ant Trip
- [欧拉回路] hdu 3018 Ant Trip
- [欧拉回路] hdu 3018 Ant Trip
- HDU 3018 Ant Trip
- hdu 3018 Ant Trip
- Hdu 3018 Ant Trip
- 欧拉路径 hdu 3018 Ant Trip
- hdu 3018 Ant Trip
- hdu acm 3018 Ant Trip
- hdu 3018 Ant Trip
- hdu 3018 Ant Trip
- HDU 3018 Ant Trip
- hdu 3018 Ant Trip
- hdu 3018 图 欧拉回路 并查集
- hdu ——3018——Ant Trip(一笔画问题)
- HDU - 3018 Ant Trip(欧拉回路一笔画+并查集)
- HDU 3018 Ant Trip 笔记
- HDU 3018(欧拉回路)
- hdu 3018 欧拉路定理+并查集