hdu3018 Ant Trip
2016-02-01 11:42
357 查看
#include <stdio.h> #include <cstdio> #include <string.h> #include <vector> #include <cstring> using namespace std; const int N = 100005; int pre , vis , du , countt ; int n, m; vector <int> a; void init() { int i; a.clear(); memset(vis, 0, sizeof(vis)); memset(du, 0, sizeof(du)); memset(countt, 0, sizeof(countt)); for(i = 1; i <= n; i ++) pre[i] = i; } int findd(int x) { int r = x; while(r != pre[r]) r = pre[r]; pre[x] = r; int i = x, j; if(i != r) { j = pre[i]; pre[i] = r; i = j; } return r; } void Union(int x, int y) { int f1, f2; f1 = findd(x); f2 = findd(y); if(f1 != f2) pre[f2] = f1; } int main() { // freopen("in.txt", "r", stdin); int i, p1, p2, k, sum; while(~scanf("%d%d", &n, &m) && n) { init(); while(m --) { scanf("%d%d", &p1, &p2); du[p1] ++; du[p2] ++; Union(p1, p2); } for(i = 1; i <= n; i ++) { k = findd(i); if(!vis[k]) { a.push_back(k); vis[k] = 1; } if(du[i] % 2 == 1) countt[k] ++; } sum = 0; for(i = 0; i < a.size(); i ++) { k = a[i]; if(du[k] == 0) continue; if(countt[k] == 0) sum ++; else sum += (countt[k] / 2); } printf("%d\n", sum); } return 0; }
心得:本题有几个点学到了:
1、vector的运用,标准模板库的容器操作和应用场合还不熟悉,其实数组也可以代替vector,但比如a.size等操作大大简化了代码,这也是前人给我们的资源;
2、孤立点也需一笔画出不要忘记,也要存入vector;
3、一个联通分量中,画的笔数 == (奇数节点的个数 / 2),注意是个数而不是度数和,刚开始我不信后来举了几个例子信了= =;
4、一半比较难一点的并查集还是把find、union、init分成函数把,放在main里太不好操作了。。。
是时候改用代码块了。。。以前贴到博客上的通常都多一个空行。。。
相关文章推荐
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 5592 ZYB's Premutation 线段树(查找动态区间第K大)
- HDU 5240 Exam (好水的题)
- HDU5237 Base64 大模拟
- HDU 1000
- HDU 1001
- 2015-11-11 hdu新生赛 A题(AC)
- 2015-11-11 hdu新生赛 C题(结束后一发AC)
- 2015-11-11 hdu新生赛 E题(结束后一发AC)
- 2015-11-11 hdu新生赛 F题(结束后一发AC)
- hdu-5385