最小费用最大流

SPFA

#include
using namespace std;
const int MAXN = 1000;
const int MAXM = 10000;
const int INF = 0x3f3f3f3f;

struct Edge{
    int v,c,w,nxt;
    // v 表示边的另一个顶点,
    // c 表示当前剩余容量,
    // w 表示单位流量费用
}e[MAXM];

int head[MAXN],s,t,tot;
// s 表示源点,t 表示汇点,需要在进行 costflow 之前设置完毕

void init(){
    memset(head,-1,sizeof(head));
    tot=0;
}

void addedge(int u,int v,int c,int w){
    e[tot].v=v;e[tot].c=c;e[tot].w=w;
    e[tot].nxt=head[u];
    head[u]=tot++;
}

bool vis[MAXN];
int d[MAXN];
int pre[MAXN];

bool spfa(){
    memset(vis,0,sizeof(vis));
    memset(d,0x3f,sizeof(d));
    memset(pre,-1,sizeof(pre));
    d[s]=0;
    vis[s]=true;
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=e[i].nxt){
            if(e[i].c){
                int v=e[i].v;
                if(d[u]+e[i].wif(!vis[v]){
                        q.push(v);
                        vis[v]=true;
                    }
                }
            }
        }
    }
    return (pre[t]!=-1);
}

int costflow(){
    // 计算最小费用最大流
    int ret=0;  // 累加和
    while(spfa()){
        int flow=INF;
        for(int i=t;i!=s;i=e[pre[i]^1].v){
            flow=min(e[pre[i]].c,flow);
            // 计算当前增广路上的最小流量
        }
        for(int i=t;i!=s;i=e[pre[i]^1].v){
            e[pre[i]].c-=flow;
            e[pre[i]^1].c+=flow;
            ret+=e[pre[i]].w*flow;
        }
    }
    return ret;
}

int main(){

    return 0;
}
const int MAX_N = 1000;
const int MAX_M = 10000;
const int inf = 0x3f3f3f3f;

struct edge {
    int v, c, w, next;  // v 表示边的另一个顶点,c 表示当前剩余容量,w 表示单位流量费用
} e[MAX_M];
int p[MAX_N], s, t, eid;  // s 表示源点,t 表示汇点,需要在进行 costflow 之前设置完毕
void init() {
    memset(p, -1, sizeof(p));
    eid = 0;
}
void insert(int u, int v, int c, int w) {
    e[eid].v = v;
    e[eid].c = c;
    e[eid].w = w;
    e[eid].next = p[u];
    p[u] = eid++;
}
void addedge(int u, int v, int c, int w) {
    insert(u, v, c, w);
    insert(v, u, 0, -w);
}
bool inq[MAX_N];
int d[MAX_N];  // 如果到顶点 i 的距离是 0x3f3f3f3f,则说明不存在源点到 i 的最短路
int pre[MAX_N];  // 最短路中连向当前顶点的边的编号
bool spfa() {  // 以源点 s 为起点计算单源最短路,如果不存在从 s 到 t 的路径则返回 false,否则返回 true
    memset(inq, 0, sizeof(inq));
    memset(d, 0x3f, sizeof(d));
    memset(pre, -1, sizeof(pre));
    d[s] = 0;
    inq[s] = true;
    queue<int> q;
    q.push(s);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        inq[u] = false;
        for (int i = p[u]; i != -1; i = e[i].next) {
            if (e[i].c) {
                int v = e[i].v;
                if (d[u] + e[i].w < d[v]) {
                    d[v] = d[u] + e[i].w;
                    pre[v] = i;
                    if (!inq[v]) {
                        q.push(v);
                        inq[v] = true;
                    }
                }
            }
        }
    }
    return pre[t] != -1;
}

int costflow() {  // 计算最小费用最大流
    int ret = 0;  // 累加和
    while(spfa()) {
        int flow = inf;
        for(int i = t; i != s; i = e[pre[i]^1].v) {
            flow = min(e[pre[i]].c, flow);  // 计算当前增广路上的最小流量
        }
        for(int i = t; i != s; i = e[pre[i]^1].v) {
            e[pre[i]].c -= flow;
            e[pre[i]^1].c += flow;
            ret += e[pre[i]].w * flow;
        }
    }
    return ret;
}
#include 
#include 
#include 
using namespace std;
const int MAX_N = 1000;
const int MAX_M = 10000;
const int inf = 0x3f3f3f3f;

struct edge{
    int v,c,w,next;
}e[MAX_M];
int p[MAX_N],s,t,eid;

void init(){
    memset(p,-1,sizeof(p));
    eid=0;
}

void insert(int u,int v,int c,int w){
    e[eid].v=v;
    e[eid].c=c;
    e[eid].w=w;
    e[eid].next=p[u];
    p[u]=eid++;
}

void addedge(int u,int v,int c,int w){
    insert(u,v,c,w);
    insert(v,u,0,-w);
}

bool inq[MAX_N];
int d[MAX_N];
int pre[MAX_N];

bool spfa(){
    memset(inq,0,sizeof(inq));
    memset(d,0x3f,sizeof(d));
    memset(pre,-1,sizeof(pre));
    d[s]=0;
    inq[s]=true;
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        inq[u]=false;
        for(int i=p[u];i!=-1;i=e[i].next){
            if(e[i].c){
                int v=e[i].v;
                if(d[u]+e[i].wif(!inq[v]){
                        q.push(v);
                        inq[v]=true;
                    }
                }
            }
        }
    }
    return pre[t]!=-1;
}

int costflow(){
    int ret=0;
    while(spfa()){
        int flow=inf;
        for(int i=t;i!=s;i=e[pre[i]^1].v){
            flow=min(e[pre[i]].c,flow);
        }
        for(int i=t;i!=s;i=e[pre[i]^1].v){
            e[pre[i]].c-=flow;
            e[pre[i]^1].c+=flow;
            ret+=e[pre[i]].w*flow;
        }
    }
    return ret;
}

int main() {
    int n,m;
    init();
    cin>>n>>m;
    for(int i=0;iint u,v,c,w;
        cin>>u>>v>>c>>w;
        addedge(u,v,c,w);
    }
    cin>>s>>t;
    cout<return 0;
}

你可能感兴趣的:(#,网络流及二分图,最小费用最大流)