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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

费用流:spfa Dijkstra

發布時間:2024/4/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 费用流:spfa Dijkstra 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 最小費用最大流
  • 最大費用最小流,建邊的時候,把花費和流量調換位置
  • 最大費用最大流,建邊的時候,把正向的費用存為負值,結果取負號
spfa模板
int path[maxn], dis[maxn], head[maxn], vis[maxn], cnt; void init() {cnt = 0;memset(head, -1, sizeof(head)); } struct ac{int v, c, cost, nex; }edge[maxn << ];void addedge(int u, int v, int c, int cost) {// 正向建邊edge[cnt] = {v, c, cost, head[u]};head[u] = cnt++;// 反向建邊edge[cnt] = {u, 0, -cost, head[v]};head[v] = cnt++; } int spfa(int s, int e) {memset(vis, 0, sizeof(vis));memset(dis, inf, sizeof(dis)); // 記錄從s點出發到每個點的費用和最小值memset(path, -1, sizeof(path)); // 記錄更新當前點的邊在edge中的下標queue<int> que;que.push(s);dis[s] = 0;vis[s] = 1;while (!que.empty()) {int u = que.front();que.pop();vis[u] = 0;// 遍歷u的所有出邊for (int i = head[u]; i != -1; i = edge[i].nex) {int v = edge[i].v;int c = edge[i].c;int cost = edge[i].cost;// 判斷是否更新v點if (dis[v] > dis[u] + cost && c > 0) {dis[v] = dis[u] + cost; // 更新最小費用path[v] = i;if (vis[v]) continue;vis[v] = 1;que.push(v);}}}return dis[e] != inf; // 判斷s能否到達e } int MincostMaxflow(int s, int e, int &cost) {int maxflow = 0;while (spfa(s, e)) { // 搜先spfa看是否存在增廣路,如果存在求一條費用和最小的一條int flow = inf; // 遍歷增廣路上的邊,取最小的流量flow// path存的是那條邊更新到這個點, i = 這個點在edge中的下標// edge[i^1].v 通過反向邊得到前驅節點for (int i = path[e]; i != -1; i = path[edge[i^1].v]) {flow = min(flow, edge[i].c); // 取最小的流量}// 得到最小流量flow之后,更改正反向的流量for (int i = path[e]; i != -1; i = path[edge[i^1].v]) {edge[i].c -= flow;edge[i^1].c += flow;cost += flow * edge[i].cost;}maxflow += flow;}return maxflow; // 返回最大流 }
Dijkstra+鏈式Dijkstra + 鏈式Dijkstra+
int preE[maxn], preV[maxn], dis[maxn], head[maxn], vis[maxn], h[maxn], cnt; void init() {cnt = 0;memset(head, -1, sizeof(head)); } struct ac{int v, c, cost, nex; }edge[maxn << 8];void addedge(int u, int v, int c, int cost) {edge[cnt] = {v, c, cost, head[u]};head[u] = cnt++;edge[cnt] = {u, 0, -cost, head[v]};head[v] = cnt++; } int Dijkstra(int s, int e) {memset(dis, inf, sizeof(dis));preE[s] = -1, dis[s] = 0;priority_queue< pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>> >que;que.push(pair<int,int>(0, s));while (!que.empty()) {pair<int, int> top = que.top();que.pop();int u = top.second;if (dis[u] < top.first) continue;for (int i = head[u]; i != -1; i = edge[i].nex) {int v = edge[i].v;int cost = edge[i].cost;int c = edge[i].c;if (c > 0 && dis[v] > dis[u] + cost + h[u] - h[v]) {dis[v] = dis[u] + cost + h[u] - h[v];preE[v] = i;preV[v] = u;que.push(pair<int,int>(dis[v], v));}}}return dis[e] != inf; } int MincostMaxflow(int s, int e, int &cost) {int maxflow = 0;memset(h, 0, sizeof(h));while (Dijkstra(s, e)) { // 搜先spfa看是否存在增廣路,如果存在求一條費用和最小的一條for (int i = 0; i <= e; ++i) h[i] += dis[i];int flow = inf; for (int i = e; i != s; i = preV[i]) {flow = min(flow, edge[preE[i]].c); // 取最小的流量}for (int i = e; i != s; i = preV[i]) {edge[preE[i]].c -= flow;edge[preE[i]^1].c += flow;}cost += flow * h[e];maxflow += flow;}return maxflow; // 返回最大流 }
Dijkstra+VectorDijkstra + VectorDijkstra+Vector
int preE[maxn], preV[maxn], dis[maxn], h[maxn]; struct ac{int v, c, cost, nex; }; vector<ac> g[maxn]; void init() {for (int i = 0; i < maxn; ++i) g[i].clear(); } void addedge(int u, int v, int c, int cost) {g[u].push_back({v, c, cost, (int)g[v].size()});g[v].push_back({u, 0, -cost, (int)g[u].size()-1}); } int Dijkstra(int s, int e) {priority_queue< pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>> >que;que.push(pair<int,int>(0, s));memset(dis, inf, sizeof(dis));dis[s] = 0;while (!que.empty()) {pair<int, int> top = que.top();que.pop();int u = top.second;if (dis[u] < top.first) continue;for (int i = 0; i < (int)g[u].size(); ++i) {int v = g[u][i].v;int cost = g[u][i].cost;int c = g[u][i].c;if (c > 0 && dis[v] > dis[u] + cost + h[u] - h[v]) {dis[v] = dis[u] + cost + h[u] - h[v];preE[v] = i;preV[v] = u;que.push(pair<int,int>(dis[v], v));}}}return dis[e] != inf; } 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的费用流:spfa Dijkstra的全部內容,希望文章能夠幫你解決所遇到的問題。

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