【题目描述】
有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
【输入】
n(城市数,1<≤n≤100)
e(边数)
以下e行,每行3个数i,j,wiji,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
做这题的时候oj平台刚改测试数据,咋都过不了
注意:
这题就是输出俩个城市之间的路,那么prim对于处理俩点之间的这种输出,肯定不如kruskal要舒服的多,注意在输入数据的时候要保证小的在前,是为了输出做准备的,这对题目是没有影响的因为并查集就是相当于无向图
#include<bits/stdc++.h>
using namespace std;
struct node
{
int from,to;
int dis;
friend bool operator <(node A,node B)
{
return A.dis<B.dis;
}
}s[1000005],t[10005];
int p[15000];
bool cmp(node A,node B)
{
if(A.from==B.from){
return A.to<B.to;
}
else return A.from<B.from;
}
int n,m;
int cnt=0;
int findth(int x)
{
if(x==p[x]) return x;
return p[x]=findth(p[x]);
}
void unionn(int x,int y)
{
int xx=findth(x);
int yy=findth(y);
if(xx!=yy) p[yy]=xx;
}
void Kruskal()
{
sort(s+1,s+1+m);
for(int i=1;i<=m;i++){
if(findth(s[i].from)==findth(s[i].to)) continue;
unionn(s[i].from,s[i].to);
t[++cnt].from=s[i].from;
t[cnt].to=s[i].to;
t[cnt].dis=s[i].dis;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) p[i]=i;
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
if(a>b) swap(a,b);
s[i].from=a;
s[i].to=b;
s[i].dis=c;
}
Kruskal();
sort(t+1,t+1+cnt,cmp);
for(int i=1;i<=cnt;i++){
cout<<t[i].from<<" "<<t[i].to<<endl;
}
return 0;
}