- 題目描述:
-
最小生成樹大家都已經很瞭解,次小生成樹就是圖中構成的樹的權值和第二小的樹,此值也可能等於最小生成樹的權值和,你的任務就是設計一個算法計算圖的最小生成樹。
- 輸入:
-
存在多組數據,第一行一個正整數t,表示有t組數據。
每組數據第一行有兩個整數n和m(2<=n<=100),之後m行,每行三個正整數s,e,w,表示s到e的雙向路的權值爲w。
- 輸出:
-
輸出次小生成樹的值,如果不存在輸出-1。
- 樣例輸入:
-
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
- 樣例輸出:
-
4
6
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
突發奇想,不想用Dijkstra算法,就自己想了一下,每次將已經確定的最短路徑的所有點與所有未確定的所有點之間的最短的那一條路徑找到,然後把找到的最短路徑相連的未確定的那個點加入到已經確定的集合中去,發現效率果然比Dijkstra低,畢竟每次要遍歷n*n級數的邊,邊的遍歷改成堆排序應該好很多,但估計也沒有dijkstra效率高。。。。
-
找出最短路徑就好辦了,將每條在此路徑上的邊砍去,再求一次最短路徑就好了。
-
效率不是很高,代碼凌亂,不建議看了
-
-
#include<iostream> using namespace std; bool aluesd(bool*a,int n) { while(n>0) { if(a[n]==false) return false; n--; } return true; } int kru(int v[102][102],int n,int m) { int j,k; bool used[102]={false}; used[1]=true; int vn[102][2]; int vnlen=0; int minp1,minp2,min; bool fd=false; int sm=0; while(!aluesd(used,n)) { min=2147483647; fd=false; for(k=1;k<=n;k++) if(used[k]) for(j=1;j<=n;j++) { if(v[k][j]>0&&v[k][j]<min&&!used[j]) { min=v[k][j]; minp1=k; minp2=j; fd=true; } } if(!fd) break; else { used[minp1]=true; used[minp2]=true; vn[vnlen][0]=minp1; vn[vnlen][1]=minp2; sm=sm+min; vnlen++; } } if(fd) return sm; else return -1; } int main() { int t; int j,k; while(cin>>t&&t!=0) { for(;t>0;t--) { int v[102][102]={0}; int n,m,p1,p2; cin>>n>>m; for(j=0;j<m;j++) { cin>>p1>>p2; cin>>v[p1][p2]; v[p2][p1]=v[p1][p2]; } bool used[102]={false}; used[1]=true; int vn[102][2]; int vnlen=0; int minp1,minp2,min; bool fd=false; int sm=0; while(!aluesd(used,n)) { min=2147483647; fd=false; for(k=1;k<=n;k++) if(used[k]) for(j=1;j<=n;j++) { if(v[k][j]>0&&v[k][j]<min&&!used[j]) { min=v[k][j]; minp1=k; minp2=j; fd=true; } } if(!fd) break; else { used[minp1]=true; used[minp2]=true; vn[vnlen][0]=minp1; vn[vnlen][1]=minp2; sm=sm+min; vnlen++; } } if(!fd) cout<<-1<<endl; else { int vtemp,pt,pt2; pt=sm; bool iss=false; for(j=0;j<vnlen;j++) { vtemp=v[vn[j][0]][vn[j][1]]; v[vn[j][0]][vn[j][1]]=0; v[vn[j][1]][vn[j][0]]=0; pt2=kru(v,n,m); v[vn[j][0]][vn[j][1]]=vtemp; v[vn[j][1]][vn[j][0]]=vtemp; if(pt2!=-1) { if(!iss) pt=pt2; else pt=pt<pt2?pt:pt2; iss=true; } } if(iss) cout<<pt<<endl; else cout<<-1<<endl; } } } return 0; } /************************************************************** Problem: 1249 User: 午夜小白龍 Language: C++ Result: Accepted Time:260 ms Memory:1520 kb ****************************************************************/
-