我正在研究MCMF(最低成本 - 最大流量)算法。
我完成了对MCMF代码的编码,但它仍然会出现运行时错误。
我无法找到原因。
我尽力找到它发生的原因,但我找不到解决方案。
我认为我的输入数据没有问题。
这是我的代码。
struct MCMF{
struct edge{
int to, cap, cost, rev;
};
int size, src, sink;
vector<vector<edge> > G;
vector<int> dist, par, edgeIdx;
MCMF(int size, int src, int sink){
G = vector<vector<edge> >(size);
par = vector<int>(size);
edgeIdx = vector<int>(size);
this->size = size;
this->src = src;
this->sink = sink;
}
bool spfa(){
dist = vector<int>(size, inf);
vector<bool> inQ = vector<bool>(size, false);
queue<int> q;
q.push(src);
inQ[src] = true;
dist[src] = 0;
while(!q.empty()){
int here = q.front();
q.pop();
inQ[here] = false;
for(int i = 0 ; i < (int)G[here].size(); i++){
auto e = G[here][i];
if(e.cap > 0 && dist[here] + e.cost < dist[e.to]) {
dist[e.to] = dist[here] + e.cost;
par[e.to] = here;
edgeIdx[e.to] = i;
if(!inQ[e.to]) q.push(e.to), inQ[e.to] = true;
}
}
}
return dist[sink] != inf;
}
pair<int,int> getMCMF(){
int maxFlow = 0;
int minCost = 0;
while(1){
if(!spfa()) break;
int minFlow = inf;
int costSum = 0;
for(int p = sink; p != par[p]; p = par[p]){
auto& e = G[par[p]][edgeIdx[p]];
minFlow = min(minFlow, e.cap);
costSum += e.cost;
}
for(int p = sink; p != par[p]; p = par[p]){
auto& e = G[par[p]][edgeIdx[p]];
e.cap -= minFlow;
G[e.to][e.rev].cap += minFlow;
}
maxFlow += minFlow;
minCost += costSum * minFlow;
}
return {maxFlow, minCost};
}
void addEdge(int from, int to, int cap, int cost){
G[from].push_back({to, cap, cost, (int)G[to].size()});
G[to].push_back({from, 0, -cost, (int)G[from].size()-1});
}
};
答案 0 :(得分:1)
我认为你应该添加代码
par[src] = src
如果您不想更改
for(int p = sink; p != par[p]; p = par[p])
我认为如果你改变
会更好p != par[p]
到
p != src
在你的for循环中。
因为理解代码更清楚,你不必添加'par [src] = src'
如果您更正我所说的部分
,这是完整的代码struct MCMF{
struct edge{
int to, cap, cost, rev;
};
int size, src, sink;
vector<vector<edge> > G;
vector<int> dist, par, edgeIdx;
MCMF(int size, int src, int sink){
G = vector<vector<edge> >(size);
par = vector<int>(size);
edgeIdx = vector<int>(size);
this->size = size;
this->src = src;
this->sink = sink;
}
bool spfa(){
dist = vector<int>(size, inf);
vector<bool> inQ = vector<bool>(size, false);
queue<int> q;
q.push(src);
inQ[src] = true;
dist[src] = 0;
while(!q.empty()){
int here = q.front();
q.pop();
inQ[here] = false;
for(int i = 0 ; i < (int)G[here].size(); i++){
auto e = G[here][i];
if(e.cap > 0 && dist[here] + e.cost < dist[e.to]) {
dist[e.to] = dist[here] + e.cost;
par[e.to] = here;
edgeIdx[e.to] = i;
if(!inQ[e.to]) q.push(e.to), inQ[e.to] = true;
}
}
}
return dist[sink] != inf;
}
pair<int,int> getMCMF(){
int maxFlow = 0;
int minCost = 0;
while(1){
if(!spfa()) break;
int minFlow = inf;
int costSum = 0;
for(int p = sink; p != src; p = par[p]){
auto& e = G[par[p]][edgeIdx[p]];
minFlow = min(minFlow, e.cap);
costSum += e.cost;
}
for(int p = sink; p != src; p = par[p]){
auto& e = G[par[p]][edgeIdx[p]];
e.cap -= minFlow;
G[e.to][e.rev].cap += minFlow;
}
maxFlow += minFlow;
minCost += costSum * minFlow;
}
return {maxFlow, minCost};
}
void addEdge(int from, int to, int cap, int cost){
G[from].push_back({to, cap, cost, (int)G[to].size()});
G[to].push_back({from, 0, -cost, (int)G[from].size()-1});
}
};