1. 程式人生 > >codevs 1003 電話連線

codevs 1003 電話連線

生成樹 col output ace all pre rim edi 發現

題目描述 Description

一個國家有n個城市。若幹個城市之間有電話線連接,現在要增加m條電話線(電話線當然是雙向的了),使得任意兩個城市之間都直接或間接經過其他城市有電話線連接,你的程序應該能夠找出最小費用及其一種連接方案。

技術分享 輸入描述 Input Description

輸入文件的第一行是n的值(n<=100).

第二行至第n+1行是一個n*n的矩陣,第i行第j列的數如果為0表示城市i與城市j有電話線連接,否則為這兩個城市之間的連接費用(範圍不超過10000)。

輸出描述 Output Description

輸出文件的第一行為你連接的電話線總數m,第二行至第m+1行為你連接的每條電話線,格式為i j,(i<j), i j是電話線連接的兩個城市。輸出請按照Prim算法發現每一條邊的順序輸出,起始點為1.

第m+2行是連接這些電話線的總費用。

樣例輸入 Sample Input

5

0 15 27 6 0

15 0 33 19 11

27 33 0 0 17

6 19 0 0 9

0 11 17 9 0

樣例輸出 Sample Output

2

1 4

2 5

17

數據範圍及提示 Data Size & Hint

n<=100

分析:

prim最小生成樹的模版題。。。

剛開始寫了個kruskle,才發現路線輸出順序不對QAQ

直接prim,距離不為0時,記錄路線,最後輸出即可。

#include<iostream>
#include<algorithm>
using
namespace std; int a[110][110],dis[110],book[110]; int from[110]; int record[110][2]; const int inf=9999999; int main() { int n,m=1,ans=0,cnt=0; cin>>n; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j)cin>>a[i][j]; for(int i=1;i<=n;++i)dis[i]=inf; dis[1]=0; for(int
i=1;i<=n;++i) { int temp=inf,t; for(int j=1;j<=n;++j) { if(dis[j]<temp&&book[j]==0)temp=dis[j],t=j; } book[t]=1; ans+=temp; for(int j=1;j<=n;++j) { if(a[t][j]<dis[j]&&book[j]==0) { dis[j]=a[t][j]; from[j]=t; } } if(temp) { ++cnt; record[cnt][0]=min(t,from[t]); record[cnt][1]=max(t,from[t]); } } cout<<cnt<<endl; for(int i=1;i<=cnt;++i) { cout<<record[i][0]<<" "<<record[i][1]<<endl; } cout<<ans; return 0; }

codevs 1003 電話連線