GHOJ 1017 传送机

题目大意

         有一个校园有$n$个路口,$m$条双向道路($1 leqslant n leqslant 100000$,$1 leqslant m leqslant 500000$)。黄黄同学想把每条路走一次且只走一次,他有一个传送机,可以把他从一个路口穿送到任意另一个路口,他至少要传送多少次才能游遍校园。

         注意:可以从任意路口开始,任意路口结束,且不一定要游遍所有路口。

题解

         容易想到,对于每个点,如果度数为奇数(奇点),那必然要从这个点传送走或必须要从其他点穿送到这个点。

         那么,如果有两个奇点,实际上我们只用传送一次,就是从第一个奇点传送到第二个奇点,这时,实际上我们不需要从第二个奇点传送出去了。

         题目中给出注意,那就是提醒我们有多张连通图。我们把只有一个点的图忽略 ,此时有$t$张图,那么图之间要传送$t - 1$次。

         根据贪心策略,对于每张连通图,我们都要从奇点开始遍历。

         也就是说,对于每张连通图,我们设图内奇点数量为$c$,此时要在图内传送(不包括从一张图传送到另一张图),当$c = 0$,不需要传送;否则,传送次数为$lfloor frac{c}{2} floor - 1$(图内遍历从第一个奇点开始)。

#include <iostream>
#include <cstdio>
#include <cctype>

#define MAX_N (100000 + 5)
#define MAX_M (500000 + 5)

using namespace std;

char buf[1 << 21], * p1 = buf, * p2 = buf;

int Getc() 
{
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1== p2) ? EOF : *p1++;
}

int n, m;
int r[MAX_N];
int d[MAX_M]; // degree
int g[MAX_N];
int c[MAX_N], tot;
int ans;

int Read()
{
    int res = 0;
    char ch = Getc();
    while(isdigit(ch) ^ 1) ch = Getc();
    while(isdigit(ch)) res = res * 10 + ch - '0', ch = Getc();
    return res;
}

int Root(int x)
{
    int R = x, tmp;
    while(R != r[R]) R = r[R];
    while(x != r[x]) tmp = r[x], r[x] = R, x = tmp;
    return R;
}
    
int main()
{
    n = Read();
    m = Read();
    if(!m) return putchar('0'), 0;
    for(register int i = 1; i <= n; ++i)
    {
        r[i] = i;
    }
    int u, v;
    for(register int i = 1; i <= m; ++i)
    {
        u = Read();
        v = Read();
        ++d[u];
        ++d[v];
        u = Root(u);
        v = Root(v);
        if(u != v) r[u] = v;
    }
    for(register int i = 1; i <= n; ++i)
    {
        if(d[i])
        {
            u = Root(i);
            if(!g[u]) g[u] = ++tot;
            if(d[i] & 1) ++c[g[u]];
        }
    }
    ans = tot - 1;
    for(register int i = 1; i <= tot; ++i)
    {
        if(c[i]) ans += (c[i] >> 1) - 1;
    }
    printf("%d", ans);
    return 0;
}
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/11275509.html