链接
题目描述
给出n个点m条边的一张无向图,求至少删掉多少条边才能让编号不超过k的点都不在任何一个环上。
思路
很显然删关键点的边最优
那么就先把不连关键点的边全连上,然后像最小生成树一样用并查集搞一搞就好了
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n, m, k, t, ans;
int fa[10000005];
struct node
{
int u, v;
}h[10000005];
int read()
{
int x = 0, flag = 1; char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') flag = -1; ch = getchar();}
while (ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0'; ch = getchar();}
return x * flag;
}
int find(int x)
{
return (fa[x] == x)?(fa[x]):(fa[x] = find(fa[x]));
}
void work()
{
for(int i = 1; i <= m; ++i)
{
if(h[i].u <= k || h[i].v <= k) {
if(find(h[i].u) == find(h[i].v))
ans++;//判断是否在一个连通块里,如果在就要删边
else fa[find(h[i].u)] = find(h[i].v);
}
}
printf("%d", ans);
}
int main()
{
n = read(); m = read(); k = read();
for(int i = 1; i <= n; ++i)
fa[i] = i;
for(int i = 1; i <= m; ++i) {
h[i].u = read(), h[i].v = read();
if (h[i].u > k && h[i].v > k)
fa[find (h[i].u)] = find (h[i].v);
}
work();
return 0;
}