• hdu 3416 Marriage Match IV (最短路+最大流)


    hdu 3416 Marriage Match IV

    Description
    Do not sincere non-interference。
    Like that show, now starvae also take part in a show, but it take place between city A and B. Starvae is in city A and girls are in city B. Every time starvae can get to city B and make a data with a girl he likes. But there are two problems with it, one is starvae must get to B within least time, it’s said that he must take a shortest path. Other is no road can be taken more than once. While the city starvae passed away can been taken more than once.

    So, under a good RP, starvae may have many chances to get to city B. But he don’t know how many chances at most he can make a data with the girl he likes . Could you help starvae?

    Input
    The first line is an integer T indicating the case number.(1<=T<=65)
    For each case,there are two integer n and m in the first line ( 2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the number of the roads.

    Then follows m line ,each line have three integers a,b,c,(1<=a,b<=n,0

    题目大意:有n个城市m条路,从城市A到城市B的最短路径有几条。

    解题思路:先正向反向求最短路,获得起点到每点的最短距离d1[]。 终点到每点的最短距离d2[],最短路Min。然后遍历每一条边。当d1[edges.from]+edges.dis+d2[edges.to]==Min时。将该边增加最大流的图中,容量为1,建完图后,以A为源点,B为汇点跑最大流就可以。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    #include <queue>
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int N = 2005;
    const int M = 200005;
    typedef long long ll;
    int n, m, s, t, Min;
    
    struct Edge{  
        int from,to;  
        ll dist;  
    };  
    struct HeapNode{
        int d,u;  
        bool operator < (const HeapNode& rhs) const{  
            return d > rhs.d;  
        }  
    };  
    
    struct Dinic{
        int ec, head[N], first[N], que[N], lev[N];
        int Next[M], to[M], v[M];
    
        void init() {
            ec = 0;
            memset(first, -1, sizeof(first));
        }
    
        void addEdge(int a,int b,int c) {
            to[ec] = b;
            v[ec] = c;
            Next[ec] = first[a];
            first[a] = ec++;
    
            to[ec] = a;
            v[ec] = 0;
            Next[ec] = first[b];
            first[b] = ec++;
        }
    
        int BFS() {
            int kid, now, f = 0, r = 1, i;
            memset(lev, 0, sizeof(lev));
            que[0] = s, lev[s] = 1;
            while (f < r) {
                now = que[f++];
                for (i = first[now]; i != -1; i = Next[i]) {
                    kid = to[i];    
                    if (!lev[kid] && v[i]) {
                        lev[kid] = lev[now] + 1;    
                        if (kid == t) return 1;
                        que[r++] = kid;
                    }
                }
            }
            return 0;
        }
    
        int DFS(int now, int sum) {
            int kid, flow, rt = 0;
            if (now == t) return sum;
            for (int i = head[now]; i != -1 && rt < sum; i = Next[i]) {
                head[now] = i;  
                kid = to[i];
                if (lev[kid] == lev[now] + 1 && v[i]) {
                    flow = DFS(kid, min(sum - rt, v[i]));
                    if (flow) {
                        v[i] -= flow;
                        v[i^1] += flow;
                        rt += flow;
                    } else lev[kid] = -1;   
                }           
            }
            return rt;
        }
    
        int dinic() {
            int ans = 0;
            while (BFS()) {
                for (int i = 0; i <= n; i++) {
                    head[i] = first[i];
                }           
                ans += DFS(s, INF);
            }
            return ans;
        }   
    }din;
    
    struct Dijkstra{  
        int n,m;               //点数和边数  
        vector<Edge> edges;    //边列表  
        vector<int> G[M];     //每一个结点出发的边编号(从0開始编号)  
        bool done[N];         //是否已永久标号  
        int d[N];             //s到各个点的距离  
        ll L; 
    
        void init(int n) {  
            this->n = n;  
            for(int i = 0; i <= m * 2; i++) G[i].clear();//清空邻接表  
            edges.clear();//清空边表  
        }  
    
        void addEdge(int from, int to, ll dist) {   
            //假设是无向图。每条无向边需调用两次AddEdge  
            edges.push_back((Edge){from, to, dist});  
            m = edges.size();  
            G[from].push_back(m - 1);  
        }  
    
        void dijkstra(int s) {//求s到全部点的距离  
            priority_queue<HeapNode> Q;  
            for(int i = 0; i <= n; i++) d[i] = INF;  
            d[s] = 0;  
            memset(done, 0, sizeof(done));  
            Q.push((HeapNode){0, s});  
            while(!Q.empty()){  
                HeapNode x = Q.top(); Q.pop();  
                int u = x.u;  
                if(done[u]) continue;  
                done[u] = true;  
                for(int i = 0; i < G[u].size(); i++){  
                    Edge& e = edges[G[u][i]];  
                    if(d[e.to] > d[u] + e.dist){  
                        d[e.to] = d[u] + e.dist;  
                        Q.push((HeapNode){d[e.to], e.to});  
                    }  
                }  
            }  
        }  
    
    }dij, dij2;  
    
    void input() {
        int u, v, d;
        scanf("%d %d", &n, &m);
        dij.init(n);
        dij2.init(n);
        for (int i = 0; i < m; i++) {
            scanf("%d %d %d", &u, &v, &d);      
            dij.addEdge(u, v, d);
            dij2.addEdge(v, u, d);
        }
        scanf("%d %d", &s, &t);
        dij.dijkstra(s);
        dij2.dijkstra(t);
        Min = dij.d[t];
    }
    
    void solve() {
        din.init();
        for (int i = 0; i < m; i++) {
            if (dij.d[dij.edges[i].from] + dij2.d[dij.edges[i].to] + dij.edges[i].dist == Min) {
                din.addEdge(dij.edges[i].from, dij.edges[i].to, 1);
            }
        }
        printf("%d
    ", din.dinic());
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            input();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    读取csv遇到的双循环
    hadoop环境配置
    mysql的查询
    mysql的基本操作
    mysql与python的交互
    设置自动获取IP和DNS
    pyecharts绘制地图
    集合 set方法
    字符串 string方法
    字典 dict方法
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7073711.html
Copyright © 2020-2023  润新知