hdu3416

来源:互联网 发布:qq三国79js奥义三板斧 编辑:程序博客网 时间:2024/05/27 06:12
http://acm.hdu.edu.cn/showproblem.php?pid=3416



Marriage Match IV

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


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
 

Author
starvae@HDU
 
题意:

有N个city,m条路线,每条路线有一个花费;

输入   n,m;

下面是m行,每行三个数字,a,b,c;

表示有a到b,路长度为C

最后一行两个数字,A,B

问有A到B,路径最短,花费最小,的路线哟多少条


1   求出最短路径d1(由A出发的最短路径),d2(由B出发的最短路径),

2  删除非最短路径的边   (d1【a】+d2【b】+c==d1【B])

3 计算最大流,即将最短路径的路线加入();


#include <iostream>#include <stdio.h>#include <queue>#include <string.h>#include <vector>const int maxn=1e5+10;const int inf=0x3f3f3f3f;using namespace std;struct edge{    int v,cost;    edge (int _v=0,int _cost=0):v(_v),cost(_cost) {}};int V;vector<edge>G[maxn];int d[maxn];void add_edge1(int from,int to,int w){    edge e;    e.v=to;    e.cost=w;    G[from].push_back(e);}bool vis[maxn];int cnt[maxn];int dist[maxn];void dijkstra(int s){    memset(vis,false,sizeof(vis));    for(int i=0; i<=V; i++)        d[i]=inf;    d[s]=0;    vis[s]=true;    queue<int>que;    while(!que.empty())        que.pop();    que.push(s);    memset(cnt,0,sizeof(cnt));    cnt[s]=1;    while(!que.empty())    {        int u=que.front();        que.pop();        vis[u]=false;        for(int i=0; i<G[u].size(); i++)        {           int v=G[u][i].v;           if(d[v]>d[u]+G[u][i].cost)           {               d[v]=d[u]+G[u][i].cost;               if(!vis[v])               {                   vis[v]=true;                   que.push(v);               }           }        }    }}int a[maxn],b[maxn],c[maxn];int d1[maxn],d2[maxn];///ISAPconst int maxm=400010;struct Edge{    int to,next,cap,flow;}edgeflow[maxm];int tol;int head[maxn];int gap[maxn],dep[maxn],pre[maxn],cur[maxn];void init(){    tol=0;    memset(head,-1,sizeof(head));}void add_edgef(int from,int to,int w,int rw=0){   edgeflow[tol].to=to;   edgeflow[tol].cap=w;   edgeflow[tol].next=head[from];   edgeflow[tol].flow=0;   head[from]=tol++;   edgeflow[tol].to=from;   edgeflow[tol].cap=rw;   edgeflow[tol].next=head[to];   edgeflow[tol].flow=0;   head[to]=tol++;}int sap(int start,int end){    int N=V;    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memset(cur,0,sizeof(cur));    int u=start;    pre[u]=-1;    gap[0]=N;    int ans=0;    while(dep[start]<N)    {        if(u==end)        {            int Min=inf;            for(int i=pre[u];i!=-1;i=pre[edgeflow[i^1].to])                if(Min>edgeflow[i].cap-edgeflow[i].flow)                    Min=edgeflow[i].cap-edgeflow[i].flow;            for(int i=pre[u];i!=-1;i=pre[edgeflow[i^1].to])            {                edgeflow[i].flow+=Min;                edgeflow[i^1].flow-=Min;            }            u=start;            ans+=Min;            continue;        }        bool flag=false;        int v;        for(int i=cur[u];i!=-1;i=edgeflow[i].next)        {            v=edgeflow[i].to;            if(edgeflow[i].cap-edgeflow[i].flow&&dep[v]+1==dep[u])            {                flag=true;                cur[u]=pre[v]=i;                break;            }        }        if(flag)        {            u=v;            continue;        }        int Min=N;        for(int  i=head[u];i!=-1;i=edgeflow[i].next)        {            if(edgeflow[i].cap-edgeflow[i].flow&&dep[edgeflow[i].to]<Min)            {                Min=dep[edgeflow[i].to];                cur[u]=i;            }        }        gap[dep[u]]--;        if(!gap[dep[u]])        return ans;        dep[u]=Min+1;        gap[dep[u]]++;        if(u!=start)            u=edgeflow[pre[u]^1].to;    }    return ans;}int main(){    int m;    int t,A,B;    cin>>t;    while(t--)    {        init();        scanf("%d%d",&V,&m);        for(int i=0; i<=V; i++)            G[i].clear();        for(int i=0; i<m; i++)        {            scanf("%d%d%d",&a[i],&b[i],&c[i]);            add_edge1(a[i],b[i],c[i]);        }        scanf("%d%d",&A,&B);        dijkstra(A);        memcpy(d1,d,sizeof(d));        for(int i=0; i<=V; i++)            G[i].clear();        for(int i=0; i<m; i++)            add_edge1(b[i],a[i],c[i]);        dijkstra(B);        memcpy(d2,d,sizeof(d));        for(int i=0; i<m; i++)        {            if(a[i]!=b[i]&&d1[a[i]]+d2[b[i]]+c[i]==d1[B])                add_edgef(a[i],b[i],1);        }        int ans=sap(A,B);        printf("%d\n",ans);    }    return 0;}





0 0