Catalog
Ant Trip-题解

查看原题请戳这里
因为每条边都只能走一次,所以这道题可以用欧拉路的性质来求解。
我们首先用并查集去记录每一个联通块,然后再统计每一个子图的奇点数,如果是偶数则满足欧拉回路的性质直接ans++ 就好了,如果是奇数,那么需要的蚂蚁数则是奇点数/2
附一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<iostream>
#include<cstring>
#include<algorithm>
#define re register

using namespace std;

int read()
{
register int a = 0,f = 1; register char ch;
ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();}
while(ch <='9' && ch >='0') {a = a * 10 + ch - 48; ch = getchar();}
return a * f;
}

int n,m,x,y,s,ans,cnt,t,d[100005],fa[100005],use[100005],a[100005],add[100005];

int find(int p)
{
if(fa[p] == p) return p;
return fa[p] = find(fa[p]);
}

void work()
{
m = read();
ans = 0;
for(re int i = 1; i <= n; i++) fa[i] = i;
for(re int i = 1; i <= n; i++) d[i] = 0;
for(re int i = 1; i <= n; i++) a[i] = 0;
for(re int i = 1; i <= n; i++) add[i] = 0;
for(re int i = 1; i <= m; i++)
{
x = read(); y = read();
d[x] ++; d[y] ++;
if(find(x) != find(y))
fa[find(y)] = find(x);
}
for(int i = 1; i<= n; i++)
{
a[find(i)]++;
if(d[i] % 2 == 1) add[find(i)] ++;
}

for(int i = 1; i <= n; i++)
{
if(a[i] <= 1) continue; //只有一个点和空的点集没有边,可以忽略不计。
else if(add[i] == 0) ans += 1;
else if(add[i] > 0) ans += add[i]/2;
}
cout << ans << endl;
}
int main()
{
while(cin >> n) work();
return 0;
}
Author: wflight
Link: http://yoursite.com/2019/08/02/Ant Trip-题解/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶

Comment