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

来源:互联网 发布:哪里胡杨林最美 知乎 编辑:程序博客网 时间:2024/06/05 23:40

Problem 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<c<=1000)it means there is a road from a to b and it's distance is c, while there may have no road from b to a. There may have a road from a to a,but you can ignore it. If there are two roads from a to b, they are different.

At last is a line with two integer A and B(1<=A,B<=N,A!=B), means the number of city A and city B.
There may be some blank line between each case.
 

Output
Output a line with a integer, means the chances starvae can get at most.
 

Sample Input
37 81 2 11 3 12 4 13 4 14 5 14 6 15 7 16 7 11 76 71 2 12 3 11 3 33 4 13 5 14 6 15 6 11 62 21 2 11 2 21 2
 

Sample Output
211

这题的就是让你求从A到B有多少条不同的最短路,什么叫做不同的最短路呢,就是任意两条最短路上都没有相同的边,因为是最短路嘛,所以每一条的距离都是相同的、最短的。

这样我们就可以把只要在任意一条最短路上的边加到网络里,然后跑一波最大流,最大的流量就是要求的答案。

那么怎么找到所有最短路上的边呢,我们可以从起点和终点分别跑一次最短路,用dis1[i]表示用起点到i点的最短距离,用dis2[i]表示从终点到i点的最短距离(这里的dis2是反向建边求出的最短距离),那么对于一条边(x,y,z),如果dis1[x] + dis2[y] + z == dis1[B],那么这条边就肯定是某一条最短路上的边。

边建好了就可以跑最大流了。


#include<queue>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn = 1100;const int inf = 1e8;struct edge{    int from, to, cap, flow;};struct dinic{    int n,m,s,t;    vector<edge> edges;    vector<int> g[maxn];    bool b[maxn];    int dis[maxn];    int cur[maxn];    void initial(int n)    {        for(int i=0;i<=n;i++)            g[i].clear();        edges.clear();    }    void addedge(int from,int to,int cap)    {        edges.push_back((edge){from,to,cap,0});        edges.push_back((edge){to,from,0,0});        m = edges.size();        g[from].push_back(m-2);        g[to].push_back(m-1);    }    bool bfs()    {        memset(b,0,sizeof(b));        queue<int> q;        q.push(s);        b[s] = 1;        dis[s] = 0;        while(!q.empty())        {            int x = q.front();            q.pop();            for(int i=0;i<g[x].size();i++)            {                edge &e = edges[g[x][i]];                if(!b[e.to] && e.cap > e.flow)                {                    b[e.to] = 1;                    dis[e.to] = dis[x] + 1;                    q.push(e.to);                }            }        }        return b[t];    }    int dfs(int x,int a)    {        if(x == t || a == 0)            return a;        int flow = 0,f;        for(int& i = cur[x];i<g[x].size();i++)        {            edge& e = edges[g[x][i]];            if(dis[x] + 1 == dis[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow)))>0)            {                e.flow += f;                edges[g[x][i]^1].flow -= f;                flow += f;                a -= f;                if(a == 0)                    break;            }        }        return flow;    }    int maxflow(int s ,int t)    {        int flow = 0;        while(bfs())        {            memset(cur,0,sizeof(cur));            flow += dfs(s,inf);        }        return flow;    }}DC;struct Edge{    int to,cost;    Edge(int a,int b)    {        to = a;        cost = b;    }    friend bool operator <(Edge a,Edge b)    {        return a.cost > b.cost;    }};int n,m;int dis1[maxn],dis2[maxn];vector<Edge> e1[maxn];vector<Edge> e2[maxn];void dj(int s,vector<Edge> *e,int *dis){    int i,j;    priority_queue<Edge> q;    for(i=1;i<=n;i++)        dis[i] = inf;    dis[s] = 0;    q.push(Edge(s,0));    while(!q.empty())    {        Edge t = q.top();        q.pop();        for(i=0;i<e[t.to].size();i++)        {            Edge es = e[t.to][i];            if(dis[es.to] > dis[t.to] + es.cost)            {                dis[es.to] = dis[t.to] + es.cost;                q.push(Edge(es.to,dis[es.to]));            }        }    }}int main(void){    int T,i,j,A,B;    scanf("%d",&T);    DC.s = 0;    while(T--)    {        scanf("%d%d",&n,&m);        DC.t = n+1;        DC.initial(DC.t);        for(i=1;i<=n;i++)        {            e1[i].clear();            e2[i].clear();        }        for(i=1;i<=m;i++)        {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            if(x == y)                continue;            e1[x].push_back(Edge(y,z));            e2[y].push_back(Edge(x,z));        }        scanf("%d%d",&A,&B);        dj(A,e1,dis1);        dj(B,e2,dis2);        DC.addedge(DC.s,A,inf);        for(i=1;i<=n;i++)        {            for(j=0;j<e1[i].size();j++)            {                int t = e1[i][j].to;                if(dis1[i] + dis2[t] + e1[i][j].cost == dis1[B])                {                    DC.addedge(i,t,1);                }            }        }        DC.addedge(B,DC.t,inf);        int ans = DC.maxflow(DC.s,DC.t);        cout << ans << endl;    }    return 0;}


0 0