您的位置:首页 > 其它

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

2015-08-13 10:02 274 查看

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为汇点跑最大流即可。

[code]#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
, first
, que
, lev
;
    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
;         //是否已永久标号  
    int d
;             //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\n", din.dinic());
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        input();
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: