费用流:spfa Dijkstra
生活随笔
收集整理的這篇文章主要介紹了
费用流:spfa Dijkstra
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
- 最小費(fèi)用最大流
- 最大費(fèi)用最小流,建邊的時(shí)候,把花費(fèi)和流量調(diào)換位置
- 最大費(fèi)用最大流,建邊的時(shí)候,把正向的費(fèi)用存為負(fù)值,結(jié)果取負(fù)號(hào)
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點(diǎn)出發(fā)到每個(gè)點(diǎn)的費(fèi)用和最小值memset(path, -1, sizeof(path)); // 記錄更新當(dāng)前點(diǎn)的邊在edge中的下標(biāo)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點(diǎn)if (dis[v] > dis[u] + cost && c > 0) {dis[v] = dis[u] + cost; // 更新最小費(fèi)用path[v] = i;if (vis[v]) continue;vis[v] = 1;que.push(v);}}}return dis[e] != inf; // 判斷s能否到達(dá)e } int MincostMaxflow(int s, int e, int &cost) {int maxflow = 0;while (spfa(s, e)) { // 搜先spfa看是否存在增廣路,如果存在求一條費(fèi)用和最小的一條int flow = inf; // 遍歷增廣路上的邊,取最小的流量flow// path存的是那條邊更新到這個(gè)點(diǎn), i = 這個(gè)點(diǎn)在edge中的下標(biāo)// edge[i^1].v 通過(guò)反向邊得到前驅(qū)節(jié)點(diǎn)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+鏈?zhǔn)紻ijkstra + 鏈?zhǔn)?/span>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看是否存在增廣路,如果存在求一條費(fèi)用和最小的一條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位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的费用流:spfa Dijkstra的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: HDU Problem - 4292 F
- 下一篇: POJ 2516 -- Minimum