HDU_3416_Marriage Match IV(最短路+最大流)

来源:互联网 发布:威斯敏斯特大学 知乎 编辑:程序博客网 时间:2024/06/05 01:58

Marriage Match IV

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2728    Accepted Submission(s): 826



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,每条路只能一次,问最多能走多少次最短路。

分析:最短路+最大流。先用最短路预处理出起点与终点到所有点的最短路,然后对于所有的边(u,v,d)判断一下是否在最短路径上(dis[s][u]+d+dis[t][v]==dis[u][t]),保留下这些有用边,容量都为1,然后跑一遍最大流即可。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3416

代码清单:
#include<map>#include<set>#include<cmath>#include<queue>#include<stack>#include<cctype>#include<string>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>using namespace std;#define end() return 0typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;const int maxN = 1000 + 5;const int maxn = 10000 + 5;const int maxv = 100000 + 5;const int INF = 0x7f7f7f7f;struct Edge{    int from,to,cap,flow;    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};struct dinic{    int n,m,s,t; //结点数,边数(包括反向弧),源点,汇点    vector<Edge>edge;//边表。edge[e]和edge[e^1]互为反向弧    vector<int>G[maxn];//邻接表。G[i][j]表示结点i的第j条边在e数组的序号    bool vis[maxn]; //bfs用    int d[maxn]; //从起点到i的距离    int cur[maxn]; //当前弧下标    void init(int n,int s,int t){        this -> n = n;        this -> s = s;        this -> t = t;        for(int i=0;i<=n;i++) G[i].clear();        edge.clear();    }    void addEdge(int from,int to,int cap){        edge.push_back(Edge(from,to,cap,0));        edge.push_back(Edge(to,from,0,0));        m=edge.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    bool bfs(){        memset(vis,false,sizeof(vis));        queue<int>q;        q.push(s);        d[s]=0;        vis[s]=true;        while(!q.empty()){            int x=q.front();q.pop();            for(int i=0;i<G[x].size();i++){                Edge& e=edge[G[x][i]];                if(!vis[e.to]&&e.cap>e.flow){ //只考虑残量网络中的弧                    vis[e.to]=true;                    d[e.to]=d[x]+1;                    q.push(e.to);                }            }        }        return vis[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=edge[G[x][i]];            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){                e.flow+=f;                edge[G[x][i]^1].flow-=f;                flow+=f;                a-=f;                if(a==0) break;            }        }        return flow;    }    int maxflow(){        int flow=0;        while(bfs()){            memset(cur,0,sizeof(cur));            flow+=dfs(s,INF);        }        return flow;    }};struct EDGE{    int to,dis;    EDGE(){}    EDGE(int v,int d):to(v),dis(d){}};int T;int N,M,st,ta;int A[maxv],B[maxv],C[maxv];vector<EDGE>graph[maxN];int dist[2][maxN];bool vist[maxN];dinic dc;void input(){    scanf("%d%d",&N,&M);    for(int i=1;i<=N;i++) graph[i].clear();    for(int i=1;i<=M;i++){        scanf("%d%d%d",&A[i],&B[i],&C[i]);        graph[A[i]].push_back(EDGE(B[i],C[i]));    }    scanf("%d%d",&st,&ta);}void spfa(int s){    int pose=(s==st)?0:1;    memset(dist[pose],INF,sizeof(dist[pose]));    memset(vist,false,sizeof(vist));    queue<int>q;    while(!q.empty()) q.pop();    dist[pose][s]=0;    vist[s]=true;    q.push(s);    while(!q.empty()){        int p=q.front();q.pop();        vist[p]=false;        for(int i=0;i<graph[p].size();i++){            EDGE& e=graph[p][i];            if(dist[pose][e.to]>dist[pose][p]+e.dis){                dist[pose][e.to]=dist[pose][p]+e.dis;                if(!vist[e.to]){                    vist[e.to]=true;                    q.push(e.to);                }            }        }    }}void createGraph(){    dc.init(N,st,ta);    for(int i=1;i<=M;i++){        if(dist[0][A[i]]+dist[1][B[i]]+C[i]==dist[0][ta]){            dc.addEdge(A[i],B[i],1);        }    }}void solve(){    spfa(st);    for(int i=1;i<=N;i++) graph[i].clear();    for(int i=1;i<=M;i++) graph[B[i]].push_back(EDGE(A[i],C[i]));    spfa(ta);    createGraph();    printf("%d\n",dc.maxflow());}int main(){    scanf("%d",&T);    while(T--){        input();        solve();    }end();}


0 0
原创粉丝点击