【并查集】Day6-B

链接

B

题目描述

给出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;
} 

Supongo que te gusta

Origin blog.csdn.net/LTH060226/article/details/119702063
Recomendado
Clasificación