luogu P1656 炸铁路题解

原题链接:

炸铁路 - 洛谷https://www.luogu.com.cn/problem/P1656

题目描述

A 国派出将军uim,对 B 国进行战略性措施,以解救涂炭的生灵。

B 国有 n 个城市,这些城市以铁路相连。任意两个城市都可以通过铁路直接或者间接到达。

uim 发现有些铁路被毁坏之后,某两个城市无法互相通过铁路到达。这样的铁路就被称为 key road。

uim 为了尽快使该国的物流系统瘫痪,希望炸毁铁路,以达到存在某两个城市无法互相通过铁路到达的效果。

然而,只有一发炮弹(A 国国会不给钱了)。所以,他能轰炸哪一条铁路呢?

输入格式

第一行 n,m (1≤n≤150,1≤m≤5000),分别表示有 n 个城市,总共 m  条铁路。

以下 m 行,每行两个整数 a, b,表示城市 a 和城市 b 之间有铁路直接连接。

输出格式

输出有若干行。

每行包含两个数字 aa,bb,其中 a<ba<b,表示 <a,b><a,b> 是 key road。

请注意:输出时,所有的数对 <a,b><a,b> 必须按照 a 从小到大排序输出;如果a 相同,则根据 b 从小到大排序。

输入输出样例

输入 #1复制

6 6
1 2
2 3
2 4
3 5
4 5
5 6

输出 #1复制

1 2
5 6

思路:

        本题数据范围较小一下就AC了,暴力枚举哪条铁路被炸,使用并查集维护每个城市之间的联通性。枚举某条铁路被炸,即将除了本条铁路之外的其他铁路所连接的城市用并查集连起来,如果炸本条铁路后的联通块为1则不是keyroad,若炸掉本条铁路联通块大于1则是keyroad。

AC代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y;
	node(){
	}
	node(int x1,int y1):x(x1),y(y1){
	}
}e[5005],ans[5005];//用于维护铁路和keyroad

int cnt;
int f[5005];
int n,m;
bool cmp(node a,node b){
	return a.x!=b.x?a.x<b.x:a.y<b.y;
}
int find(int x){
	return f[x]==x?x:f[x] = find(f[x]); 
}
void uni(int x,int y){
	f[find(x)] = find(y);
}
void keyroad(int x){//x为本次要炸的铁路,只要不将这条铁路连起来就行 
	for(int i = 1;i<=m;++i){
		if(i!=x){
			uni(e[i].x,e[i].y);
		}
	}
	int t = 0;
	for(int i = 1;i<=n;++i){
		if(f[i]==i)	t++;
	}
	if(t>1){
		ans[++cnt] = node(min(e[x].x,e[x].y),max(e[x].x,e[x].y));//答案要求最终的x要小于y 
	}
}
int main(){
	cin>>n>>m;
	for(int i = 1;i<=m;++i){
		cin>>e[i].x>>e[i].y;
	}
	for(int i = 1;i<=m;++i){//枚举要炸的铁路 
		for(int i = 1;i<=n;++i)	f[i] = i;
		keyroad(i);
	}
	sort(ans+1,ans+cnt+1,cmp);
	for(int i = 1;i<=cnt;++i){
		cout<<ans[i].x<<" "<<ans[i].y<<endl;
	}
	return 0;
}

        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值