CF1209D Cow and Snacks 题解
题意:
$n$ 种小吃,$k$ 个客人,每个人喜欢两种编号不同的小吃。但是每种小吃在小吃店里只有
一坨。客人按顺序进入小吃店,会买走所有她喜欢且仍在店铺里的小吃。如果一个客人买不到任何一束小吃,那么她就会十分沮丧导致变成肥宅。现在你可以自己安排这 $k$ 个人的顺序,使得肥宅的数量最小。
注意,只拿到一种小吃的客人不会变成肥宅。
输入格式:
The first line contains integers $n$ and $k$ ( $2 \le n \le 10^5$ , $1 \le k \le 10^5$ ), the number of snacks and the number of guests.
The $ i $ -th of the following $k$ lines contains two integers $x_i$ and $y_i$ ( $1 \le x_i, y_i \le n$ , $x_i \ne y_i$ ), favorite snack flavors of the $ i $ -th guest.
输出格式:
Output one integer, the smallest possible number of sad guests.
如果客人 $i$ 喜欢吃 $u_i,v_i$ ,则我们将 $u_i,v_i$ 连一条无向边。
考虑并查集维护。如果合并成功,则肥宅数量减少 $1$ 。
时间复杂度 $\mathcal{O}(n)$
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(1e5+15))
int n,k,res,f[N],sz[N];
void init(int n) { for(int i=1; i<=n; i++) f[i] = i, sz[i] = 1; }
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
bool merge(int u,int v)
{
int x = find(u), y = find(v);
if(x == y) return 0;
if(sz[x] > sz[y]) swap(x,y);
f[x] = y; sz[y] += sz[x]; return 1;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("check.in","r",stdin);
// freopen("check.out","w",stdout);
cin >> n >> k; init(n);
for(int i=1,u,v; i<=k; i++)
{ cin >> u >> v; res += merge(u,v); }
cout << k - res << '\n';
return 0;
}