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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ 1601 [Usaco2008 Oct]灌水 (最小生成树)

發(fā)布時(shí)間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1601 [Usaco2008 Oct]灌水 (最小生成树) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意

Farmer John已經(jīng)決定把水灌到他的n(1<=n<=300)塊農(nóng)田,農(nóng)田被數(shù)字1到n標(biāo)記。把一塊土地進(jìn)行灌水有兩種方法,從其他農(nóng)田飲水,或者這塊土地建造水庫。 建造一個(gè)水庫需要花費(fèi)Wi(1<=Wi<=100000),連接兩塊土地需要花費(fèi)Pij(1<=pij<=100000,pij=pji,pii=0). 計(jì)算Farmer John所需的最少代價(jià)。

思路

很經(jīng)典的最小生成樹模型……很久沒做最小生成樹一下子沒想出來TAT…… 首先得有個(gè)水源吧,設(shè)個(gè)虛節(jié)點(diǎn)當(dāng)水源,然后連向每個(gè)土地,權(quán)值為建造水庫的花費(fèi),其他的照常建圖,然后求最小生成樹就行了。

代碼

? [cpp] #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #define MID(x,y) ((x+y)/2) #define MEM(a,b) memset(a,b,sizeof(a)) #define REP(i, begin, end) for (int i = begin; i <= end; i ++) using namespace std; const int MAX = 305; struct edge{ int v, w; edge(){ } edge(int _v, int _w){ v = _v; w = _w; } }; struct MST{ vector <edge> adj[MAX]; int dist[MAX]; bool vis[MAX]; priority_queue <pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > PQ; void init(int n){ for (int i = 0; i <= n; i ++){ adj[i].clear(); vis[i] = false; } } void add_edge(int u, int v, int w){ adj[u].push_back(edge(v, w)); adj[v].push_back(edge(u, w)); } int solve(int s, int n){ for (int i = 0; i <= n; i ++) dist[i] = 0x3fffffff; while(!PQ.empty()) PQ.pop(); dist[s] = 0; PQ.push(make_pair(0, s)); while(!PQ.empty()){ int u = PQ.top().second; PQ.pop(); vis[u] = true; for (int i = 0; i < (int)adj[u].size(); i ++){ int v = adj[u][i].v, w = adj[u][i].w; if (!vis[v] && dist[v] > w){ dist[v] = w; PQ.push(make_pair(w, v)); } } } int res = 0; for (int i = 1; i <= n; i ++) res += dist[i]; return res; } }prim; int main(){ //freopen("test.in", "r", stdin); //freopen("test.out", "w", stdout); int n; scanf("%d", &n); prim.init(n+1); for (int i = 1; i <= n; i ++){ int tmp; scanf("%d", &tmp); prim.add_edge(n+1, i, tmp); } for (int i = 1; i <= n; i ++){ for (int j = 1; j <= n; j ++){ int tmp; scanf("%d", &tmp); if (i >= j) continue; prim.add_edge(i, j, tmp); } } printf("%d\n", prim.solve(n+1, n+1)); return 0; } [/cpp]

轉(zhuǎn)載于:https://www.cnblogs.com/AbandonZHANG/p/4114351.html

總結(jié)

以上是生活随笔為你收集整理的BZOJ 1601 [Usaco2008 Oct]灌水 (最小生成树)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。