游历校园 [COGS 614] [欧拉图]

Description

刷完牙洗完脸,黄黄同学就要上课去了。可是黄黄同学每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄黄同学想每条路也只走一遍。我们一般人很可能对一些地图是办不到每条路走一遍且仅走一遍的,但是黄黄同学有个传送机,他可以任意地将一个人从一个路口传送到任意一个路口。
可是,每传送一次是需要耗费巨大的内力的,黄黄同学希望可以用最少的传送次数完成游遍校园,你能帮助他吗 ?
因为黄黄同学只是游历校园,于是我们可以认为黄黄同学可以从任意点开始,到任意点结束。

Input

第一行有一个整数 N ,表示黄黄的校园里一共有多少路口。
第二行有一个整数 M ,表示路口之间有 M 条路。
后面 M 行每行两个整数 a 、 b 表示 a 与 b 之间有一条路,且路是双向的。

Output

只包括一个整数 s ,表示黄黄同学最少的传送次数。

Sample Input

3
2
1 2
2 3

Sample Output

0

Hint

数据范围:
对于 100 %的数据,保证 N ≤ 100000 , K ≤ 500000 , 1 ≤ a , b ≤ N 。

Solution

请教了数学组的大佬后才会做的...

对于一个连通块,要完成「一笔画」,度数为寄的点只能为0或2个,而跳一次相当于连一条边。消除两个寄点

所以当一个连通块寄点数为x>2时,要化成2个时,加的边(跳的次数)=(x-2)/2

所以bfs解决连通块就行了

但是注意!无度数的点不要考虑,因为没有边要遍历。

Code

 1 #include<queue>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define RG register int
 8 #define rep(i,a,b)    for(RG i=a;i<=b;i++)
 9 #define per(i,a,b)    for(RG i=a;i>=b;i--)
10 #define add(x,y) e[++cnt].v=y,e[cnt].next=head[x],head[x]=cnt
11 #define inf (1<<30)
12 #define maxn 100005
13 #define maxm 500005
14 using namespace std;
15 int n,m,sid,cnt,ans;
16 int head[maxn],vis[maxn],deg[maxn];
17 vector<int> vec[maxn];
18 struct E{
19     int v,next;
20 }e[maxm<<1];
21 inline int read()
22 {
23     int x=0,f=1;char c=getchar();
24     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
25     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
26     return x*f;
27 }
28 
29 void bfs(int x)
30 {
31     int sum=0;
32     queue<int> que;
33     que.push(x),vis[x]=1;
34     RG u,v;
35     while(!que.empty())
36     {
37         u=que.front(),que.pop();
38         if(deg[u]&1) ++sum;
39         for(RG i=head[u];i;i=e[i].next)
40         {
41             v=e[i].v;
42             if(!vis[v])
43                 vis[v]=1,que.push(v);
44         }
45     }
46     if(sum>2)    ans+=(sum-2)>>1;
47 }
48 
49 int main()
50 {
51 
52     n=read(),m=read();
53     RG u,v;rep(i,1,m) u=read(),v=read(),add(u,v),add(v,u),++deg[u],++deg[v];
54     rep(i,1,n)    if(!vis[i]&&deg[i]>0)    bfs(i),ans++;
55     cout<<ans-1;
56     return 0;
57 }
>>点击查看代码<<

 

posted @ 2018-04-04 17:22  iBilllee  阅读(233)  评论(0编辑  收藏  举报