zoukankan      html  css  js  c++  java
  • HDU3416 最短路+最大流

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

    题意:
    有向图求没有交集的A到B最短路的数量
     
    很显然要先将所有最短路上的边取出来。
    用正向跑一遍dis1,反向跑一遍dis2的方法
    dis1[u] + dis2[v] + w == dis1[B]的边就是最短路上的边
    但是要求没有交集的最短路,想到最大流,每一条最短路上的边都看作一条流量为1的边,直接跑最大流即可。
     
    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    #define Vec Point
    typedef vector<int> VI;
    const double eps = 1e-9;
    const int maxn = 2010;
    const int maxm = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,tmp,K;
    int A,B;
    int dis[maxn],dis1[maxn],dis2[maxn];
    struct Edge{
        int v,dis,next,flag;
    }edge[maxm * 2];
    int head[maxn],cnt; 
    int head2[maxn],tot;
    bool vis[maxn];
    struct Edge2{
        int to,next,cap,flow;
    }edge2[maxm];
    void init(){
        Mem(head,0);
        cnt = 0;
        tot = 2;
        Mem(head2,-1);
    }
    void addedge(int u,int v,int w,int rw = 0){
        edge2[tot].to = v; edge2[tot].cap = w; edge2[tot].flow = 0;
        edge2[tot].next = head2[u]; head2[u] = tot++;
        edge2[tot].to = u; edge2[tot].cap = rw; edge2[tot].flow = 0;
        edge2[tot].next = head2[v]; head2[v] = tot++;
    }
    int q[maxn];
    int dep[maxn],cur[maxn],sta[maxn];
    bool bfs(int s,int t,int n){
        int front = 0,tail = 0;
        Mem(dep,-1);
        dep[s] = 0;
        q[tail++] = s;
        while(front < tail){
            int u = q[front++];
            for(int i = head2[u]; i != -1; i = edge2[i].next){
                int v = edge2[i].to;
                if(edge2[i].cap > edge2[i].flow && dep[v] == -1){
                    dep[v] = dep[u] + 1;
                    if(v == t) return true;
                    q[tail++] = v;
                }
            }
        }
        return false;
    }
    int dinic(int s,int t,int n){
        int maxflow = 0;
        while(bfs(s,t,n)){
            for(int i = 1; i <= n ; i ++) cur[i] = head2[i];
            int u = s,tail = 0;
            while(cur[s] != -1){
                if(u == t){
                    int tp = INF;
                    for(int i = tail - 1; i >= 0; i --){
                        tp = min(tp,edge2[sta[i]].cap - edge2[sta[i]].flow);
                    }
                    maxflow += tp;
                    for(int i = tail - 1; i >= 0 ; i --){
                        edge2[sta[i]].flow += tp;
                        edge2[sta[i] ^ 1].flow -= tp;
                        if(edge2[sta[i]].cap - edge2[sta[i]].flow == 0)
                            tail = i;
                    }
                    u = edge2[sta[tail] ^ 1].to;
                }else if(cur[u] != -1 && edge2[cur[u]].cap > edge2[cur[u]].flow && dep[u] + 1 == dep[edge2[cur[u]].to]){
                    sta[tail++] = cur[u];
                    u = edge2[cur[u]].to;
                }else{
                    while(u != s && cur[u] == -1){
                        u = edge2[sta[--tail] ^ 1].to;
                    }
                    cur[u] = edge2[cur[u]].next;
                }
            }
        }
        return maxflow;
    }
    void add(int u,int v,int w,int flag){
        edge[++cnt].dis = w;
        edge[cnt].v = v;
        edge[cnt].flag = flag;
        edge[cnt].next = head[u];
        head[u] = cnt;
    }
    struct cmp{
        bool operator () (int a,int b){
            return dis[a] > dis[b];
        }
    };
    void Dijkstra(int s){
        For(i,1,N) vis[i] = 0,dis[i] = INF;
        dis[s] = 0;
        priority_queue<int,vector<int>,cmp>Q;
        Q.push(s);
        while(!Q.empty()){
            int u = Q.top(); Q.pop();
            if(vis[u]) continue;
            vis[u] = 1;
            for(int i = head[u]; i ; i = edge[i].next){
                int v = edge[i].v; int w = edge[i].dis;
                if(s == A && edge[i].flag == -1 || s == B && edge[i].flag == 1) continue;
                if(!vis[v] && dis[u] + w < dis[v]){
                    dis[v] = dis[u] + w;
                    Q.push(v);
                }
            }
        }
    }
    int main()
    {
        int T; Sca(T);
        while(T--){
            scanf("%d%d",&N,&M);
            init();
            For(i,1,M){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w,1);
                add(v,u,w,-1);
            }
            scanf("%d%d",&A,&B);
            Dijkstra(A);For(i,1,N) dis1[i] = dis[i];
            Dijkstra(B);For(i,1,N) dis2[i] = dis[i];
            For(i,1,N){
                for(int j = head[i]; j ; j = edge[j].next){
                    int v = edge[j].v,w = edge[j].dis;
                    if(dis1[i] + dis2[v] + w == dis1[B] && edge[j].flag == 1){
                        addedge(i,v,1);
                    }
                }
            }
            Pri(dinic(A,B,N));
        }
        #ifdef VSCode
        system("pause");
        #endif
        return 0;
    }
  • 相关阅读:
    第三百四十九、五十天 how can I 坚持
    第三百四十八天 how can I 坚持
    第三百四十七天 how can I 坚持
    第三百四十六天 how can I 坚持
    第三百四十五天 how can I 坚持
    第三百四十四天 how can I 坚持
    第三百四十三天 how can I 坚持
    第三百四十二天 how can I 坚持
    第三百四十一天 how can I 坚持
    POJ 2996:Help Me with the Game
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/9553233.html
Copyright © 2011-2022 走看看