题目链接
造了一个最小费用最大流的板子,可根据需求小改,O2优化后可完全AC
#include <bits/stdc++.h>
using namespace std;
class MinCostFlow {
public:
struct Result {
int flow, cost;
};
MinCostFlow(int n, int m = 0) : visited(n), head(n, -1), dist(n), prev(n) ,flow(n), preu(n){
edges.reserve(m << 1);
}
void add_edge(int u, int v, int capacity, int cost) {
internal_add_edge(u, v, capacity, cost);
internal_add_edge(v, u, 0, -cost);
}
bool spfa(int src, int dst) {
const int infdist = std::numeric_limits<int>::max();
std::fill(dist.begin(), dist.end(), infdist);
std::fill(flow.begin(), flow.end(), infdist);
dist[src] = 0;
std::queue<int> queue;
queue.push(src);
while (!queue.empty()) {
int u = queue.front();
queue.pop();
visited[u] = false;
for (int iter = head[u]; ~iter;) {
int v = edges[iter].v;
if (edges[iter].rest && dist[u] + edges[iter].cost < dist[v]) {
dist[v] = dist[u] + edges[iter].cost;
prev[v] = iter;//上一边
preu[v] = u;//前驱点
flow[v] = min(flow[u],edges[iter].rest);
if (!visited[v]) {
visited[v] = true;
queue.push(v);
}
}
iter = edges[iter].next;
}
}
return dist[dst]!=infdist;
}
Result MCMF(int src,int dst){
int maxflow=0,mincost=0;
while(spfa(src,dst)){
int v=dst;
maxflow+=flow[dst];
mincost+=flow[dst]*dist[dst];
while(v!=src){
edges[prev[v]].rest-=flow[dst];
edges[prev[v]^1].rest+=flow[dst];
v=preu[v];
}
}
return Result{maxflow,mincost};
}
private:
struct Edge {
int v, next, rest, cost;//终点,下条边,容量,花费
};
void internal_add_edge(int u, int v, int capacity, int cost) {
edges.push_back(Edge{v, head[u], capacity, cost});
head[u] = edges.size() - 1;
}
std::vector<bool> visited;
std::vector<int> head, dist, prev, flow, preu;
std::vector<Edge> edges;
};
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
int main(){
int n,m,s,t;
n=read(),m=read(),s=read(),t=read();
MinCostFlow net(n,m);
for(int i=0,u,v,w,f;i<m;i++){
u=read(),v=read(),w=read(),f=read();
net.add_edge(u-1,v-1,w,f);
}
MinCostFlow::Result ans=net.MCMF(s-1,t-1);
cout<<ans.flow<<" "<<ans.cost<<"
";
return 0;
}