3060: [Poi2012]Tour de Byteotia

3060: [Poi2012]Tour de Byteotia

Time Limit: 30 Sec   Memory Limit: 256 MB
Submit: 279   Solved: 178
[ Submit][ Status][ Discuss]

Description

给定一个n个点m条边的无向图,问最少删掉多少条边能使得编号小于等于k的点都不在环上。

Input

       第一行三个整数nmk
       接下来m行每行两个整数aibi,表示aibi之间有一条无向边。

Output

 
       一个整数,表示最少的删边数量。

Sample Input


11 13 5
1 2
1 3
1 5
3 5
2 8
4 11
7 11
6 10
6 9
2 3
8 9
5 9
9 10

Sample Output


3

HINT



数据范围:

       对于100%的数据满足:1 ≤ n ≤ 1,000,000,1 ≤ m ≤ 2,000,000,1 ≤ k ≤ n。

Source

[ Submit][ Status][ Discuss]

原图中每存在一个非法环就至少要删去上面的一条边
因此,一定存在一种最优方案,使得每次删掉的边至少一个端点的编号不超过k
优先加入端点编号都大于k的边,然后是一个不超过k,最后是都不超过k
用并查集维护就行了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

const int maxn = 1E6 + 10;

struct E{
	int x,y; E(){}
	E(int x,int y): x(x),y(y){}
}edgs[maxn*2];

int n,m,k,Ans,fa[maxn];

int getint()
{
	char ch = getchar(); int ret = 0;
	while (ch < '0' || '9' < ch) ch = getchar();
	while ('0' <= ch && ch <= '9')
		ret = ret*10 + ch - '0',ch = getchar();
	return ret;
}

int getfa(int x) {return x == fa[x] ? x : fa[x] = getfa(fa[x]);}

int main()
{
	#ifdef DMC
		freopen("DMC.txt","r",stdin);
	#endif
	
	n = getint(); m = getint(); k = getint();
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++)
	{
		int x = getint(),y = getint(); edgs[i] = E(x,y);
		if (x > k && y > k)
		{
			int fx = getfa(x),fy = getfa(y);
			if (fx != fy) fa[fx] = fy;
		}
	}
	for (int i = 1; i <= m; i++)
	{
		if (edgs[i].x > k && edgs[i].y > k) continue;
		if (edgs[i].x <= k && edgs[i].y <= k) continue;
		int fx = getfa(edgs[i].x),fy = getfa(edgs[i].y);
		if (fx != fy) fa[fx] = fy; else ++Ans;
	}
	for (int i = 1; i <= m; i++)
		if (edgs[i].x <= k && edgs[i].y <= k)
		{
			int fx = getfa(edgs[i].x),fy = getfa(edgs[i].y);
			if (fx != fy) fa[fx] = fy; else ++Ans;	
		}
	cout << Ans;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值