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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

POJ3522Slim Span(最大边与最小边差值最小的生成树)

發布時間:2025/3/19 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ3522Slim Span(最大边与最小边差值最小的生成树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

感謝這篇文章
本文對其代碼,進行一些解釋。

這道題的題意很明了。求最大邊與最小邊差值最小的生成樹

首先,把所有的生成樹都求出來是不可能的,所以,必須用別的方法。

在學習次小生成樹的過程中,知道了一個最小生成樹的性質, 一個圖的最小生成樹不一定是唯一的,但是組成這些最小生成樹的各個邊的權值一定都是一一對應相同的。不會出現這種一個樹上有兩個邊權值a+b等于另外一顆樹上兩個邊c+d,然后這兩個樹都是最小生成樹的情況。

對于本題來講,上面那個性質就說明了一個圖的最小生成樹上的最小邊的權值和最大邊的權值是固定不變的。那么當使用克魯斯卡爾算法時,第一次加入的必然是邊權最小的邊,由于克魯斯卡爾算法的正確性已經得到驗證過,那么此邊的權值必然就是最小生成樹的最小邊權值了,當最小邊的權值固定時,最小生成樹的最大邊的權值也“命中注定”是固定的,在最小邊權值固定的情況下,其他的生成樹的最大邊必然也是大于等于最小生成樹的最大邊,否則就不滿足我們上文提到的性質,這就是“當生成樹的最小邊確定時,最小生成樹的最大邊的權值是所有生成樹中最小的”。從而,我們得到了一個本題的解法。 枚舉最小邊,然后求最小生成樹,更新最優解。

代碼:

#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<string> #include<queue> #include<map> #include<stack> #include<set> //#include<unordered_map> #include<ctime> using namespace std; typedef long long ll; #define pi pair<int,int> #define mst(ss,b) memset(ss,b,sizeof(ss)); #define rep(i,k,n) for(int i=k;i<=n;i++) #define INF 0x3f3f3f3fconst int N = 1e4 + 10;// e[i] 表示第i條邊的信息(連接u和v,權值為w) struct edge {int u, v, w;edge(int u1=0,int v1=0,int w1=0):u(u1),v(v1),w(w1){}bool operator <(const edge e1){return this->w < e1.w;} }e[N];bool vis[N]; int n, m; int fa[N];void init() {for (int i = 0; i <= n; ++i)fa[i] = i; }int find(int x) {if (fa[x] == x)return x;elsereturn fa[x] = find(fa[x]); }void join(int x,int y) {x = find(x);y = find(y);if (x != y)fa[x] = fa[y]; }bool same(int a, int b) {return find(a) == find(b); }int Kruskal() {sort(e + 1, e + m+1);int flag = 0, ans = INF;//枚舉每一個最小邊,for (int i = 1; i <= m; ++i){init();//并查集初始化int cnt = 1;//以該邊來構建最小生成樹的最大邊權,和最小邊權int hight = e[i].w, low = e[i].w;//加入這條邊join(e[i].u, e[i].v);//從該邊后面的邊選邊組成最小生成樹for (int j = i+1 ; j <= m; ++j){if (!same(e[j].u, e[j].v)){join(e[j].u, e[j].v);hight = max(hight, e[j].w);cnt++;}if (cnt == n - 1)break;}if (cnt == n - 1)//如果能構成了最小生成樹{flag = 1;//更新ans = min(ans, hight - low);}}if (!flag)return -1;elsereturn ans; }int main() {while (~scanf_s("%d%d", &n, &m)&&(n||m)){mst(e, 0);for (int i = 1; i <= m; ++i)scanf_s("%d%d%d", &e[i].u, &e[i].v, &e[i].w);printf("%d\n", Kruskal());}return 0; }

總結

以上是生活随笔為你收集整理的POJ3522Slim Span(最大边与最小边差值最小的生成树)的全部內容,希望文章能夠幫你解決所遇到的問題。

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