hdu3416

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
   
   
   
   
3 7 8 1 2 1 1 3 1 2 4 1 3 4 1 4 5 1 4 6 1 5 7 1 6 7 1 1 7 6 7 1 2 1 2 3 1 1 3 3 3 4 1 3 5 1 4 6 1 5 6 1 1 6 2 2 1 2 1 1 2 2 1 2
 

Sample Output
   
   
   
   
2 1 1
 

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];
///ISAP
const 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;
}





你可能感兴趣的:(hdu3416)