hdu3018 2010.3.3

hdu3018 2010.3.3

Hdu 3018 

 

【关键字】

压缩路径的并查集+欧拉路

【摘要】

给定若干个图,求最少用几笔可将其画完(遍历所有的边,且仅遍历一次)。

【正文】

1、题目描述

Ant Trip

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 122    Accepted Submission(s): 52

 

 

ProblemDescription

Ant Country consist of N towns.There are Mroads connecting the towns.

Ant Tony,together with his friends,wants togo through every part of the country.

 

They intend to visit every road , and everyroad must be visited for exact one time.However,it may be a mission impossiblefor only one group of people.So they are trying to divide all the people intoseveral groups,and each may start at different town.Now tony wants to know whatis the least groups of ants that needs to form to achieve their goal.

 

Input

Input contains multiple cases.Test casesare separated by several blank lines. Each test case starts with two integerN(1<=N<=100000),M(0<=M<=200000),indicating that there are N townsand M roads in Ant Country.Followed by M lines,each line contains two integersa,b,(1<=a,b<=N) indicating that there is a road connecting town a andtown b.No two roads will be the same,and there is no road connecting the sametown. 

 

Output

For each test case ,output the least groupsthat needs to form to achieve their goal. 

 

SampleInput

3 3

1 2

2 3

1 3

 

4 2

1 2

3 4

 

SampleOutput

1

2

 

Hint

New ~~~ Notice: if there are no roadconnecting one town ,tony may forget about the town.

In sample 1,tony and his friends just formone group,they can start at either town 1,2,or 3.

In sample 2,tony and his friends must formtwo group.

 

Source

2009 Multi-University Training Contest 12 -Host by FZU 

 

Recommend

gaojie

2、算法分析

这道题的本质就是若干个图的min笔画问题,要求min最小。

首先要确定有几个独立的图,用到了并查集,而且还是压缩路径的。

对于每个图,如果只有偶点,那么可以一笔画;若有n个奇点,那最少要用n/2笔。

其实,比赛的时候想到了这样做,只是不会用并查集,所以,没有办法实现。写这道题的解题报告的原因就是,我学会了用压缩路径的并查集。

3、源码

#include <stdio.h>
#include <string.h>

#define MAXN 100000+10

int father[MAXN],num[MAXN],used[MAXN],ans,count[MAXN];
int n,m,i,j,a,p,b,fa,fb;

int find(int x)
{
	if (father[x]==x) return x;
	father[x]=find(father[x]);
	return father[x];
}

void main()
{
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		ans=0;
		for(i=1;i<=n;i++)
			father[i]=i;
		memset(num,0,sizeof(num));
		memset(used,0,sizeof(used));
		memset(count,0,sizeof(count));
		for(j=1;j<=m;j++)
		{
			scanf("%d %d",&a,&b);
			fa=find(a);
			fb=find(b);
			if (fa!=fb)
				father[fa]=fb;
			used[a]++;
			used[b]++;
		}
		for(j=1;j<=n;j++)
		{
			if (used[j])
			{
				p=find(j);
				count[p]++;
				if (used[j]%2==1)
					num[p]++;
			}
		}
        for(j=1;j<=n;j++)
		{
			if (count[j])
			{
				if (num[j]==0)
					ans++;
				else
					ans+=num[j]/2;
			}
		}
		printf("%d\n",ans);
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值