zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    delphi 焦点定位
    delphi cxgrid 添加分页
    推动力
    python enumerate 函数用法
    Python pass语句作用与用法
    Python 元组知识点
    python 练习多级菜单思路
    一点练习题
    优化mysql服务器
    对自己的忠告
  • 原文地址:https://www.cnblogs.com/MengX/p/11231778.html
Copyright © 2011-2022 走看看