題目描述
有N個村庄,編號從1到N,你應該建造一些道路,使每個村庄都可以相互連接。
兩個村A和B是相連的,當且僅當A和B之間有一條道路,或者存在一個村C使得在A和C之間有一條道路,並且C和B相連。
現在一些村庄之間已經有一些道路,你的任務就是修建一些道路,使所有村庄都連通起來,並且所有道路的長度總和是最小的。輸入
測試數據有多組
第一行是整數N(3 <= N <= 100),代表村庄的數量。 然后是N行,其中第i行包含N個整數,這些N個整數中的第j個是村庄i和村庄j之間的距離(距離是[1,1000]內的整數)。
然后是整數Q(0 <= Q <= N *(N + 1)/ 2),接下來是Q行,每行包含兩個整數a和b(1 <= a <b <= N),代表着村庄a和村庄b之間的道路已經建成。輸出
對於每組測試數據
輸出一個整數,表示要構建的道路的長度總和最小值
樣例輸入
3 0 990 692 990 0 179 692 179 0 1 1 2
樣例輸出
179
提示
#include<iostream> #include<cstring> using namespace std; const int maxx=0x7f; int array[maxx][maxx]; class Kru { public: int bef; int aft; int data; int flag; Kru() { bef=aft=-1; data=flag=0; } }; int find(string str[],int n,string st)///返回st字符串的下標 { for(int i=0;i<n;i++) { if(str[i]==st) return i; } return -1; } void prim(string str[],int n,int start) { int index=start;///開始遍歷的頂點 int sum=0; int visit[n]; int dist[n]; int pos[n]; memset(visit,false,sizeof(visit)); visit[index]=true; for(int i=0;i<n;i++) { dist[i]=array[index][i]; pos[i]=index*100+i;///表示index與i連通 } string bef[n]; string aft[n]; int quan[n]; int r=0; for(int i=1;i<n;i++) { int minn=0x3f3f3f3f; for(int j=0;j<n;j++) { if(!visit[j]&&dist[j]<minn) { minn=dist[j]; index=j; } } visit[index]=true; bef[r]=str[pos[index]/100]; aft[r]=str[index]; quan[r]=dist[index]; r++; sum+=dist[index]; for(int j=0;j<n;j++) { if(!visit[j]&&dist[j]>array[index][j]) { dist[j]=array[index][j]; pos[j]=index*100+j; } } } cout<<sum<<endl; } int main() { int n; while(cin>>n) { string str[maxx]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cin>>array[i][j]; } } int Q; cin>>Q; for(int i=0;i<Q;i++) { int b,a; cin>>b>>a; array[b-1][a-1]=0; array[a-1][b-1]=0; } for(int i=0;i<n;i++) { char c='0'+i; str[i]+=c; } string s="0"; int d=find(str,n,s); prim(str,n,d); } return 0; }