Farmer John變得很是懶,他不想再繼續維護供奶牛之間供通行的道路。道路被用來鏈接N個牧場,牧場被連續地編號爲1到N。每個牧場都是一個奶牛的家。FJ計劃除去P條道路中儘量多的道路,可是還要保持牧場之間 的連通性。你首先要決定那些道路是須要保留的N-1條道路。第j條雙向道路鏈接了牧場Sj和Ej(1 <= Sj <= N; 1 <= Ej <= N; Sj != Ej),並且走完它須要Lj的時間。沒有兩個牧場是被一條以上的道路所鏈接。奶牛們很是傷心,由於她們的交通系統被削減了。你須要到每個奶牛的住處去安慰她們。每次你到達第i個牧場的時候(即便你已經到過),你必須花去Ci的時間和奶牛交談。你每一個晚上都會在同一個牧場(這是供你選擇的)過夜,直到奶牛們都從悲傷中緩過神來。在早上 起來和晚上回去睡覺的時候,你都須要和在你睡覺的牧場的奶牛交談一次。這樣你才能完成你的 交談任務。假設Farmer John採納了你的建議,請計算出使全部奶牛都被安慰的最少時間。ios
第1行包含兩個整數N和P。算法
接下來N行,每行包含一個整數Ci。數組
接下來P行,每行包含三個整數Sj, Ej和Lj。ide
5 <= N <= 10000,N-1 <= P <= 100000,0 <= Lj <= 1000,1 <= Ci <= 1,000。學習
1 #include<iostream> 2 using namespace std; 3 const int in = 1000; 4 int main() 5 { 6 int N,P; 7 int c[101]; 8 int l[101][101] = {0}; 9 cin >>N>>P; 10 int i; 11 for(i = 0;i < N;i++) 12 { 13 cin >> c[i]; 14 } 15 int j,k; 16 for(k = 0;k < P;k++) 17 { 18 int c; 19 cin >>i>>j; 20 cin>>c; 21 l[i - 1][j - 1] = l[j - 1][i - 1] = c; 22 } 23 int map[101][101]; 24 for(i = 0;i < N;i++) 25 { 26 for(j = 0;j < N;j++) 27 { 28 if(l[i][j] == 0)map[i][j] = in; 29 else map[i][j] = 2*l[i][j]+c[i]+c[j]; 30 } 31 } 32 int cost[101]; 33 int point[101]; 34 bool visit[101]; 35 for(i = 0;i < N;i++) 36 { 37 cost[i] = map[0][i]; 38 point[i] = 0; 39 visit[i] = false; 40 } 41 visit[0] = true; 42 for(k = 1;k<N;k++) 43 { 44 int min = in; 45 j = 0; 46 for(i = 0;i < N;i++) 47 { 48 if(!visit[i] && min > cost[i]){min = cost[i];j = i;} 49 } 50 visit[j] = true; 51 for(i = 0;i < N;i++) 52 { 53 if(!visit[i] && cost[i] > map[j][i]){cost[i] = map[j][i];point[i] = j;} 54 } 55 } 56 int min = c[0]; 57 for(i = 0;i < N;i++) 58 { 59 if(min > c[i])min = c[i]; 60 } 61 int sum = 0; 62 for(i = 1;i < N;i++) 63 { 64 sum += map[i][point[i]]; 65 } 66 cout<<sum+min<<endl; 67 return 0; 68 }
這樣顯然是不行的,由於二階矩陣實在是太大了。因此就用鏈表存儲該圖。可是用鏈表存儲的最小生成樹算法我並不會寫。先粘一個經過的代碼。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int MAXN=10000+10; 6 const int MAXM=100000+10; 7 const int INF=100000; 8 int cost[MAXN],fa[MAXN]; 9 int find(int cur) 10 { 11 return cur==fa[cur]? cur:fa[cur]=find(fa[cur]); 12 } 13 struct edge 14 { 15 int from,to,val; 16 bool operator <(const edge& x)const{ 17 return val<x.val; 18 } 19 }e[MAXM]; 20 21 int main() 22 { 23 int mini=INF,index; 24 int n,p; 25 scanf("%d%d",&n,&p); 26 for(int i=1;i<=n;i++) 27 { 28 scanf("%d",&cost[i]); 29 mini=min(cost[i],mini); 30 fa[i]=i; 31 } 32 for(int i=0;i<p;i++) 33 { 34 scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].val); 35 e[i].val=(e[i].val<<1)+cost[ e[i].from ] + cost [ e[i].to ]; 36 } 37 sort(e,e+p); 38 int ans=0; 39 for(int i=0;i<p;i++) 40 { 41 int x=e[i].from,y=e[i].to; 42 int root_x=find(x),root_y=find(y); 43 if(root_x==root_y) continue; 44 fa[root_x]=root_y; 45 ans+=e[i].val; 46 } 47 printf("%d\n",ans+mini); 48 return 0; 49 }
等我再研究一下用鏈表的怎麼寫。spa