生成树 : P1656 炸铁路

P1656 炸铁路

https://www.luogu.com.cn/problem/P1656

题意

  • n个城市,m条铁路
  • 只有一发炮弹,炸某一条路。让其不成互相连接
  • 输出 必须按照 a 从小到大排序输出;如果a 相同,则根据 b从小到大排序。
1 2
5 6

想法

  • 生成树+遍历
  • 遍历每一条边,如果删除是否能够变为一个生成树
//
// Created by majoe on 2020/6/3.
//
#include <bits/stdc++.h>
using namespace std;
const int M = 5010,INF = 0x3f3f3f3f;
struct e{
    int u,v;
}edges[M];
int n, m;
int p[160];
//大小拍好序,好输出
bool cmp(e e1, e e2){
    if(e1.u == e2.u) return e1.v < e2.v;
    else return e1.u < e2.u;
}
int find(int x){
    if(x != p[x]) return p[x] = find(p[x]);
    return p[x];
}
//判断是否能够生成生成树,如果可以,返回true
bool kruskal(int x){
    for (int i = 1; i <= n; ++i) {
        p[i] = i;
    }

    int cnt = 0;
    //遍历所有除开 x 序号的边
    for (int i = 0; i < m; ++i) {
        if(i == x) continue;
        auto t = edges[i];
        t.u = find(t.u); t.v = find(t.v);
        if(t.u != t.v){
            p[t.u] = t.v;
            cnt ++;
        }
    }
    if (cnt >=n-1) return true;
    else {
        return false;
    }
}
int main(){
    cin >> n >> m;
    for (int i = 0; i < m; ++i) {
        int a,b;
        cin >> a >> b;
        if(a > b) swap(a,b);
        edges[i] = {a,b};//加入边
    }
    sort(edges,edges+m,cmp);
    for (int i = 0; i < m; ++i) {
        if(!kruskal(i)){
            printf("%d %d\n",edges[i].u,edges[i].v);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值