【题目描述】
有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
【输入】
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 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!