您的位置:首页 > 其它

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