1348:【例4-9】城市公交网建设问题

时间:2021-08-04 12:18:03
【题目描述】
有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
【输入】
n(城市数,1≤n≤100)
e(边数)
以下e行,每行3个数i,j,wij,表示在城市i,j之间修建高速公路的造价。
【输出】
n-1行,每行为两个城市的序号,表明这两个城市间建一条高速公路。
【输入样例】
5 8
1 2 2
2 5 9
5 4 7
4 1 10
1 3 12
4 3 6
5 3 3
2 3 8
【输出样例】
1  2
2  3
3  4
3  5
# include <bits/stdc++.h>
using namespace std ;
const int N = 100 ;
const int M = N * N ;
int n , m ;
int fa[N] ;
struct node {
    int u , v , w ;
}edge[M] , ans[N] ;
inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]) ; } 
inline void merge(int x , int y) { fa[find(x)] = find(y) ; return ; } 
inline bool cmp(node x , node y) { return x.w < y.w ; }
inline bool cmp2(node x , node y) { return x.u == y.u ? x.v < y.v : x.u < y.u ;}
inline void kruskal() {
    sort(edge + 1 , edge + m + 1 , cmp) ;
    int cnt = 0 ;
    for(register int i=1;i<=m;i++) {
        int fx = find(edge[i].u) , fy = find(edge[i].v) ;
        if(fx == fy) continue ;
        merge(edge[i].u , edge[i].v) ;
        ++ cnt ; ans[cnt].u = edge[i].u , ans[cnt].v = edge[i].v , ans[cnt].w = edge[i].w ;
    }
    sort(ans + 1 , ans + cnt + 1 , cmp2) ;
    for(register int i=1;i<=cnt;i++) {
        printf("%d %d \n" , ans[i].u , ans[i].v) ;
    }
    return ;
}
signed main() {
    ios::sync_with_stdio(false) ;
    cin >> n >> m ;
    for(register int i=1;i<=n;i++) fa[i] = i ;
    for(register int i=1;i<=m;i++) {
        int u , v , w ;
        cin >> u >> v >> w ;
        if(u > v) swap(u , v) ;
        edge[i] = node ({u , v , w}) ;
    }
    return kruskal() , 0 ;
}