日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NYOJ 118 修路方案(次小生成树)

發布時間:2025/3/16 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NYOJ 118 修路方案(次小生成树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

修路方案

時間限制:3000?ms ?|? 內存限制:65535?KB 難度:5 描述

南將軍率領著許多部隊,它們分別駐扎在N個不同的城市里,這些城市分別編號1~N,由于交通不太便利,南將軍準備修路。

現在已經知道哪些城市之間可以修路,如果修路,花費是多少。

現在,軍師小工已經找到了一種修路的方案,能夠使各個城市都聯通起來,而且花費最少。

但是,南將軍說,這個修路方案所拼成的圖案很不吉利,想讓小工計算一下是否存在另外一種方案花費和剛才的方案一樣,現在你來幫小工寫一個程序算一下吧。

輸入
第一行輸入一個整數T(1<T<20),表示測試數據的組數
每組測試數據的第一行是兩個整數V,E,(3<V<500,10<E<200000)分別表示城市的個數和城市之間路的條數。數據保證所有的城市都有路相連。
隨后的E行,每行有三個數字A B L,表示A號城市與B號城市之間修路花費為L。
輸出
對于每組測試數據輸出Yes或No(如果存在兩種以上的最小花費方案則輸出Yes,如果最小花費的方案只有一種,則輸出No)
樣例輸入
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
樣例輸出
No Yes
Prim+次小生成樹!
次小生成樹的兩種算法:
算法1、step 1.? 先用prim求出最小生成樹T.
???????? 在prim的同時,用一個矩陣max[u][v] 記錄 在T中連結任意兩點u,v的唯一的
???????? 路中權值最大的那條邊的權值. (注意這里).
???????? 這是很容易做到的,因為prim是每次增加一個結點s, 而設已經標號了的結點
???????? 集合為W, 則W中所有的結點到s的路中的最大權值的邊就是當前加入的這條邊.
???????? step 1 用時 O(V^2).
???? step 2.? 枚舉所有不在T中的邊uv, 加入邊uv則必然替換權為max[u][v]的邊。
算法2、先用prim求出最小生成樹T。
?????????? 枚舉T中的每一條邊,把它刪除,求剩下的圖的最小生成樹。選所有枚舉得到的生成樹中的最小的那一個。
AC碼:
#include<stdio.h> #include<string.h> #define INF 99999999 int G[505][505],visit[505],lowcost[505]; int repair[505][505],pre[505],f[505][505]; int main() {int T,v,e,a,b,cost,MinTree,ans,i,j,k,min;scanf("%d",&T);while(T--){scanf("%d%d",&v,&e);//memset(G,INF,sizeof(G)); // 對矩陣G賦值,只能賦為0或-1,如果賦為INF,提交不成功for(i=0;i<=v;i++){for(j=0;j<=v;j++)G[i][j]=INF;}memset(repair,0,sizeof(repair));for(i=0;i<e;i++){scanf("%d%d%d",&a,&b,&cost);G[a][b]=G[b][a]=cost;// 把該邊初始為可修狀態repair[a][b]=repair[b][a]=1; // repair:修}// Prim算法生成最小樹memset(visit,0,sizeof(visit));memset(f,0,sizeof(f));for(i=1;i<=v;i++){lowcost[i]=G[1][i]; // 初始化lowcost的值pre[i]=1; // 輔助數組}visit[1]=1;k=1;MinTree=0;for(i=1;i<=v;i++){min=INF;for(j=1;j<=v;j++){if(!visit[j]&&min>lowcost[j]){min=lowcost[j];k=j;}}if(min==INF)break;repair[pre[k]][k]=repair[k][pre[k]]=0;MinTree+=min;visit[k]=1;for(j=1;j<=v;j++){if(visit[j])f[k][j]=f[j][k]=f[j][pre[k]]>G[pre[k]][k]?f[j][pre[k]]:G[pre[k]][k];if(!visit[j]&&G[k][j]<lowcost[j]){lowcost[j]=G[k][j];pre[j]=k;}}}// 再求次小生成樹ans=INF;for(i=1;i<=v;i++){for(j=1;j<=v;j++){if(repair[i][j])ans=ans<(MinTree-f[i][j]+G[i][j])?ans:(MinTree-f[i][j]+G[i][j]);}}if(ans==MinTree)printf("Yes\n");elseprintf("No\n");}return 0; }

總結

以上是生活随笔為你收集整理的NYOJ 118 修路方案(次小生成树)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。