在最大流的基礎上,找到乙個費用最小的。
都還不知道這個演算法有沒有名字。就是spfa套乙個求最小割。
借用oj的乙個比喻。就是從a到b,有三種路線選擇,汽車,飛機,走路,假設走的路都是相同的,這時走路費用是最少的。
因此每次找一條最短路,對他求最小割(也就是最大流),然後將ans加上最大流x最短路。
(可以這樣來理解。就是以本題為模型,最短路求的是單價之和,最小割求的是最大的數量)
求最大費用最大流,思路相同,但是要改兩個地方,賦初值為負無窮,spfa中比較要反號。
要注意的地方:
1、求完最小費用最大流,不能用一開始的邊的資訊求最大費用最大流,因為殘量被修改了。
我的解決方案是建兩條相同的邊。
2、求最大費用最大流的時侯除s以外的點要賦初值為負無窮。不能賦為零,因為這樣一開始就無法對其他點鬆弛了。
3、找增廣軌的時候一定要判斷殘量是否大於零,同樣適用於這裡的找最短路。
話說這道題也可以用km來做。
題目沒有給出資料範圍,一開始就隨便取了乙個,沒想到因為空間的緣故,導致超時了。把資料規模改小了之後就過了。我想可能是因為構造函式呼叫次數太多了吧。
#include #include #include const long maxn=10000;
long m;
long n;
long s;
long t;
bool vis[maxn];
long dist[maxn];
struct node
;struct bm
;bm* head[maxn];
bm* head2[maxn];
bm* pre[maxn];
long size;
std::queueque;
const long inf = 0x7fff0000;
bool spfa()}}
}if (pre[t])return true;
return false;
}void fee_maxflow()
ans += min * dist[t];
p = pre[t];
while (p)
}while (1)
ans2 += min * dist[t];
p = pre[t];
while (p)
}printf ("%ld\n",ans);
printf ("%ld\n",ans2);
}void insert(long u,long v,long cap,long val)
void insert2(long u,long v,long cap,long val)
int main()
{ freopen("transport.in", "r", stdin);
freopen("transport.out", "w", stdout);
scanf("%ld%ld",&m,&n);
size = m+n+2;
s = size;
t = size - 1;
for (long i=n+1; i
mysql最小費用最大流問題 最小費用最大流問題
複雜網路中,單源單點的最小費用最大流演算法 mcmf 應用廣泛。在實際網路問題中,不僅考慮從 vs到 vt的流量最大,還要考慮可行流在網路傳送過程中的費用問題,這就是網路的最小費用最大流問題。最小費用最大流問題的一般提法 已知容量網路 d v a c 每條弧 vi,vj 除了已給出容量 cij 外,...
mysql最小費用最大流問題 最小費用最大流問題
最小費用最大流就是在原來求最大流的基礎上,假設每條邊還有乙個單位流量所需要的費用,因為最小費用的出現,原本的平行邊變得有意義,並且允許反向增廣,基本上就是將原本bfs改為進行一次bellmanford演算法尋找最短路徑,只要初始流是該流量下的最小費用可行流,每次增廣後的新流都是新流量下的最小費用流。...
mysql最小費用最大流問題 最小費用最大流
最小費用最大流 修改的dijkstra ford fulksonff演算法 修改的dijkstra其實和johnson演算法的思想是一致的。乙個求最小費用最大流的樸素演算法是這樣的 1求最小費用增廣路2判斷是否存在增廣路,否的話演算法終止。3增加增廣路上邊的流量4在增廣路上新增必要的逆向負權邊5go...