HDU-6582 Path 最短路+网络流

http://acm.hdu.edu.cn/showproblem.php?pid=6582

2019 多校第一场

跑两次dijstra确定最短路 然后把最短路上的边全部加入网络流 跑最小割

#include<bits/stdc++.h>
#define maxn 10005
using namespace std;
#define ll long long
const ll INF = 0x3f3f3f3f3f3f3f3f;
int head2[maxn],To2[maxn*20],Next2[maxn*20],vis[maxn];
int head[maxn],To[maxn*20],Next[maxn*20];
int dep[maxn],cur[maxn];
int cnt,S,T;
int u[maxn],v[maxn];
ll w[maxn];
ll flow[maxn*20],cost2[maxn*20],dis1[maxn],dis2[maxn];
void add(int u,int v,ll w){
    Next2[cnt]=head2[u];
    head2[u]=cnt;
    To2[cnt]=v;
    cost2[cnt++]=w;
}
void add2(int u,int v,ll w){
    Next[cnt]=head[u];
    head[u]=cnt;
    To[cnt]=v;
    flow[cnt++]=w;
}
void init(int n){
    for(int i=1;i<=n;i++){
        head[i]=-1;
        head2[i]=-1;
        dis1[i]=INF;
        dis2[i]=INF;
        vis[i]=0;
        dep[i]=0;
        cur[i]=0;
    }
    cnt=0;
}
void dij(int s,ll dis[]){
    priority_queue<pair<ll,int> , vector<pair<ll,int> > ,greater<pair<ll,int> > > q;
    q.push({0,s});
    dis[s]=0;
    while(!q.empty()){
        int u=q.top().second;
        q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head2[u];i!=-1;i=Next2[i]){
            int v=To2[i];
            if(dis[v]>dis[u]+cost2[i]){
                dis[v]=dis[u]+cost2[i];
                q.push({dis[v],v});
            }
        }
    }

}
ll dfs(int u,ll cost){
    if(u==T) return cost;
    for(int &i=cur[u];i!=-1;i=Next[i]){
        if(dep[To[i]]==dep[u]+1&&flow[i]>0){
           ll dis=dfs(To[i],min(flow[i],cost));
            if(dis>0){
                flow[i]-=dis;
                flow[i^1]+=dis;
                return dis;
            }
        }
    }
    return 0;
}
int bfs(){
    queue<int> q;
    q.push(1);
    memset(dep,0,sizeof(dep));
    dep[1]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=head[u];i!=-1;i=Next[i]){
            if(flow[i]>0&&dep[To[i]]==0){
                dep[To[i]]=dep[u]+1;
                q.push(To[i]);
            }
        }
    }
    if(dep[T]>0) return 1;
    return 0;
}
ll dicnic(){
    ll ans=0;
    while(bfs()){
        ll cost;
        for(int i=1;i<=T+2;i++){
            cur[i]=head[i];
        }
        while(cost=dfs(1,INF))
            ans+=cost;
    }
    return ans;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d %d",&n,&m);
        init(n);
        for(int i=1;i<=m;i++){
            scanf("%d %d %I64d",&u[i],&v[i],&w[i]);
            add(u[i],v[i],w[i]);
        }
        dij(1,dis1);
        for(int i=0;i<=n;i++){
            vis[i]=0;
            head2[i]=-1;
        }
        cnt=0;
        for(int i=1;i<=m;i++){
            add(v[i],u[i],w[i]);
        }
        dij(n,dis2);
        cnt=0;
        T=n;
       for(int i=1;i<=m;i++){
        if(dis1[u[i]]+w[i]+dis2[v[i]]==dis1[n]){
            add2(u[i],v[i],w[i]);
            add2(v[i],u[i],0);
        }
       }
       cout<<dicnic()<<"
";
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/MengX/p/11231778.html