打卡信奥刷题(2734)用C++实现信奥题 P3535 [POI 2012] TOU-Tour de Byteotia

P3535 [POI 2012] TOU-Tour de Byteotia

题目描述

译自 POI 2012 Stage 2. Day 0「Tour de Byteotia

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

输入格式

第一行包含三个整数 n n n m m m k k k,分别表示 n n n 个节点, m m m 条边, k k k 意义见题面。

接下来 m m m 行,每行两个整数 u u u v v v,表示一条由 u u u v v v双向边。数据保证没有重边

输出格式

第一行一个整数 c n t cnt cnt,表示最少的删边数量;

接下来 c n t cnt cnt 行,每行输出两个正整数 a , b a,b a,b,表示删除 a , b a,b a,b 之间的一条边。先输出编号小的点,再输出编号大的点。

输入输出样例 #1

输入 #1

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

输出 #1

3
2 3
5 9
3 5

说明/提示

样例配图如下:

对于 40 % 40\% 40% 的数据, n ≤ 1000 n \le 1000 n1000 m ≤ 5000 m \le 5000 m5000

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 10 6 1 \le n \le 10^6 1n106 0 ≤ m ≤ 2 × 10 6 0 \le m \le 2\times10^6 0m2×106 1 ≤ k ≤ n 1 \le k \le n 1kn 1 ≤ u < v ≤ n 1 \le u \lt v \le n 1u<vn

翻译来自于 LibreOJ

C++实现

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 2000005
int n,m,k,fa[N],cnt;
struct node {
	int x,y;
}e[N],ans[N];
int find(int x) {//并查集找根 
	if (fa[x]!=x) {
		fa[x]=find(fa[x]);
	}
	return fa[x];
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for (int i=1; i<=n; i++)fa[i]=i;//把每一个点设为自己的根,方便并集
	cin>>k;
	for (int i=1; i<=m; i++) {
		cin>>e[i].x>>e[i].y;
		if (e[i].x>k && e[i].y>k) fa[find(e[i].x)]=find(e[i].y);
	}
	for (int i=1; i<=m; i++) { 
		int u=find(e[i].x);
		int v=find(e[i].y);
		if (e[i].x<=k || e[i].y<=k) {
			if (u==v) {
				cnt++;
				ans[cnt]=e[i];
			} else fa[u]=v;
		}
	}
	cout<<cnt<<"\n";
	for (int i=1; i<=cnt; i++) {
		if (ans[i].x<ans[i].y) {
			cout<<ans[i].x<<' '<<ans[i].y<<"\n";
		} else {
			cout<<ans[i].y<<' '<<ans[i].x<<"\n";
		}
	}
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值