当前位置:网站首页>Minimum cost and maximum flow (template question)

Minimum cost and maximum flow (template question)

2022-06-24 21:10:00 GS_ Qiang

poj2125
The main idea of the topic :
Here's an undirected graph , Yes n A little bit ,m side , Seek from 1 ~ n, And then from n ~ 1 , And each side can only go once , Find the shortest path .

Ideas :
Because each side can only go once , So you can set the flow of each side to 1, Or flow through the edge , Or neither . Set the weight of each edge to the cost of that edge , Then run twice spfa The shortest way is to find the minimum cost .

Templates :

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1e3+10;
const int M=4e4+10;
int n,m,ss,tt;
int dis[N],head[M<<1],tot=1,vis[N],incf[N],pre[N];
struct edge {
    
    int to,next,w,flow;
}E[M<<1];
void add(int from,int to,int flow,int w) {
    
    E[++tot].to=to;
    E[tot].flow=flow;
    E[tot].w=w;
    E[tot].next=head[from];
    head[from]=tot;
}
bool spfa(int s,int t) {
    
    queue<int>q;
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    q.push(s);
    dis[s]=0,vis[s]=1;
    incf[s]=INF; // Infinite initial flow 
    while(!q.empty()) {
    
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=E[i].next) {
    
            if(!E[i].flow) continue;
            int to=E[i].to;
            
            if(dis[to]>dis[u]+E[i].w) {
    
                dis[to]=dis[u]+E[i].w;
                incf[to]=min(incf[u],E[i].flow);
                pre[to]=i;
                if(!vis[to]) {
    
                    vis[to]=1;
                    q.push(to);
                }
            }
        }
    }
    if(dis[t]==INF) return false;
    return true;
}
void dinic(int s,int t) {
    
    int maxflow=0;
    int mincost=0;
    while(spfa(s,t)) {
    
        int x=t;
        maxflow+=incf[t];
        mincost+=dis[t]*incf[t];
        while(x!=s) {
    
            int i=pre[x];
            E[i].flow-=incf[t];
            E[i^1].flow+=incf[t];
            x=E[i^1].to;
        }
        if(maxflow==2) break;  // The maximum flow is 2 It indicates that two to from have been found 1-n The shortest circuit of 
    }
    //if(maxflow<2) cout << "-1" << endl;  Because the data given by the topic must have two shortest paths , So this sentence is useless ,,,,,
    cout << mincost << endl;
    
}
void init() {
    
    tot=1;
    memset(head,-1,sizeof(head));
}
int main() {
    
    ios::sync_with_stdio(false);
    init();
    cin >> n >> m;
    for(int i=0;i<m;i++) {
    
        int u,v,w,x;
        cin >> u >> v >> w;
        // Because it's an undirected graph , So it's equivalent to adding 4 side 
        add(u,v,1,w);
        add(v,u,0,-w);
        add(v,u,1,w);
        add(u,v,0,-w);
    }

    dinic(1,n);
    return 0;
}
原网站

版权声明
本文为[GS_ Qiang]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211319023069.html