HDU 6582

题目链接

解法:最短路+最小割

先把代码放上来,之后再来填坑

#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int maxn=100100;
const ll INF=23333333333333;

int n, m, k;

struct edge {
    int from, to; ll cap;
    edge(int from, int to, ll cap):from(from), to(to), cap(cap){}
};
vector<edge> E;
vector<int> G[maxn];
int level[maxn], cur[maxn], inq[maxn];
ll S[maxn];

void add_edge(int from, int to, ll cap) {
    E.push_back(edge(from, to, cap));
    E.push_back(edge(to, from, 0));
    G[from].push_back(E.size()-2);
    G[to].push_back(E.size()-1);
}

void bfs(int s) {
    memset(level, -1, sizeof(level));
    level[s]=0;
    queue<int> q;
    q.push(s);
    while(!q.empty()) {
        int v=q.front(); q.pop();
        for(int i=0; i<(int)G[v].size(); i++) {
            edge e=E[G[v][i]];
            if(e.cap>0 && level[e.to]<0) {
                level[e.to]=level[v]+1;
                q.push(e.to); 
            }
        }
    }
}

ll dfs(int v, int t, ll f) {
    if(v==t) return f;
    for(int &i=cur[v]; i<(int)G[v].size(); i++) {
        edge &e=E[G[v][i]];
        if(e.cap>0 && level[v]<level[e.to]) {
            ll d=dfs(e.to, t, min(f, e.cap));
            if(d>0) {
                e.cap-=d;
                E[G[v][i]^1].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

ll dinic(int s, int t) {
    ll flow=0;
    while(1) {
        bfs(s);
        if(level[t]<0) return flow;
        memset(cur, 0, sizeof(cur));
        ll f=0;
        while((f=dfs(s, t, INF))>0) {
            flow+=f;
        }
    }
    return flow;
}

void SPFA(int s) {
    for(int i=1; i<=n; i++) S[i]=INF;
    memset(inq, 0, sizeof(inq));
    S[s]=0;
    queue<int> q;
    q.push(s); inq[s]=1;
    while(!q.empty()) {
        int v=q.front(); q.pop(); inq[v]=0;
        for(int i=0; i<(int)G[v].size(); i++) {
            edge e=E[G[v][i]];
            if(e.cap>0 && S[e.to]>S[v]+e.cap) {
                S[e.to]=S[v]+e.cap;
                if(!inq[e.to]) {
                    q.push(e.to); inq[e.to]=1;
                }
            }
        }
    }
}

int main() {
    int t;
    cin>>t;
    while(t--) {
        cin>>n>>m;
        E.clear();
        for(int i=1; i<=n; i++) G[i].clear();
        for(int i=1; i<=m; i++) {
            int x, y; ll c;
            cin>>x>>y>>c;
            add_edge(x, y, c);
        }
        SPFA(1);
        for(int i=0; i<(int)E.size(); i++) {
            edge &e=E[i];
            if(S[e.from]+e.cap != S[e.to]) {
                e.cap=0;
            }
        }
        ll ans=dinic(1, n);
        cout<<ans<<endl;
    }
    return 0;
}

/* 
2
4 7
1 2 2
1 2 1
2 3 3
1 3 2
3 4 2
1 4 4
2 4 3

3 4
1 2 1
2 3 1
1 3 2
1 3 3
*/

 

相似题目: 6590 6589 6588 6587 6586 

 

posted @ 2019-07-23 13:59  ertuan  阅读(484)  评论(0)    收藏  举报