信息学奥赛一本通T1348:最小生成树 城市公交网建设问题

【题目描述】有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?【输入】n(城市数,1<≤n≤100)e(边数)以下e行,每行3个数i,j,wij,表示在城市i,j之间修建高速公路的造价。【输

信息学奥赛一本通T1348:城市公交网建设问题

【题目描述】

有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?

【输入】

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<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 1001
#define MOD 123
#define E 1e-6
using namespace std;
int father[N];
struct Node{
    int u;
    int v;
    int w;
}g[N*N],dis[N];
void quick_sort(int left,int right)
{
    int i=left,j=right;
    int mid=g[(left+right)/2].w;
    while(i<=j)
    {
        while(g[i].w<mid)
            i++;
        while(g[j].w>mid)
            j--;
        if(i<=j)
        {
            swap(g[i],g[j]);
            i++;
            j--;
        }
    }
    if(i<right)
        quick_sort(i,right);
    if(left<j)
        quick_sort(left,j);
}
int Find(int x)
{
    if(father[x]==x)
        return x;
    return father[x]=Find(father[x]);
}
int Union(int x,int y)
{
    x=Find(x);
    y=Find(y);
    if(x!=y)
    {
        father[y]=x;
        return 1;
    }
    return 0;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        father[i]=i;
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        if(u>v)//小点在前
            swap(u,v);
        g[i].u=u;
        g[i].v=v;
        g[i].w=w;
    }

    int sum=0;
    quick_sort(1,m);
    for(int i=1;i<=m;i++)
        sum+=g[i].w;

    int cnt=0;
    for(int i=1;i<=m;i++)
        if(Union(g[i].u,g[i].v))
        {
            cnt++;
            dis[cnt].u=g[i].u;
            dis[cnt].v=g[i].v;
            dis[cnt].w=g[i].w;
            if(cnt==n-1)
                break;
        }
    for(int i=1;i<=cnt;i++)
        for(int j=i+1;j<=cnt;j++)
        {
            if(dis[i].u>dis[j].u)
                swap(dis[i],dis[j]);
            else if(dis[i].u==dis[j].u&&dis[i].v>dis[j].v)
                swap(dis[i],dis[j]);
        }

    for(int i=1;i<=cnt;i++)
        cout<<dis[i].u<<" "<<dis[i].v<<endl;
    return 0;
}

 

信息学奥赛一本通T1348:最小生成树 城市公交网建设问题 归属于 最小生成树,更多同类题解源程序见:最小生成树 和 城市公交网建设问题

0 条评论

请先 登录 后评论
不写代码的码农
轩爸

0 篇文章

作家榜 »

  1. admin 2 文章
  2. 张芳 0 文章
  3. hanna 0 文章
  4. Jason 0 文章
  5. lixiaioqian 0 文章
  6. GeraldWrora 0 文章
  7. 董伟 0 文章
  8. 信奥达人 0 文章