hdu 3416 Marriage Match IV 【网络最大流+最短路】

Marriage Match IV

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


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
 
  分析:此题题意为求最短路径数,那么可以先跑一边最短路,找出
             最短路径上的边,然后用这些变新建图,每条边权值为1,通过
             最大流求出路径数。
  代码示例:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define max 1000000000
#define Le 200000
#define Lh 20000
using namespace std;
typedef struct
{
        int to;
        int w;
        int next;
        }node;
typedef struct
{
        int x;
        int t;
        }DEP;
node E[Le],Es[Le];
DEP fir,nex;
int head[Lh],headx[Lh],heads[Lh];
int dis[Lh],deep[Lh];
int cnt,cnts,n,m;
void ADDs(int a,int b,int c)
{
     Es[++cnts].to=b;
     Es[cnts].w=c;
     Es[cnts].next=heads[a];
     heads[a]=cnts;
     }
void ADD(int a,int b,int c)
{
     E[++cnt].to=b;
     E[cnt].w=c;
     E[cnt].next=head[a];
     head[a]=cnt;
     E[++cnt].to=a;
     E[cnt].w=0;
     E[cnt].next=head[b];
     head[b]=cnt;
     }
int min(int x,int y)
{
    return x<y?x:y;
}
int bfs(int s,int t,int n)
{
    memset(deep,255,sizeof(deep));
    queue<DEP>Q;
    fir.x=s;
    fir.t=0;
    deep[s]=0;
    Q.push(fir);
    while(!Q.empty())
    {
        fir=Q.front();
        Q.pop();
        for(int i=head[fir.x];i;i=E[i].next)
        {
            nex.x=E[i].to;
            nex.t=fir.t+1;
            if(deep[nex.x]!=-1||!E[i].w)
            continue;
            deep[nex.x]=nex.t;
            Q.push(nex);
        }
    }
    for(int i=0;i<=n;i++)
    headx[i]=head[i];
   return deep[t]!=-1;
}
int dfs(int s,int t,int flow)
{
    if(s==t)
    return flow;
    int newflow=0;
    for(int i=headx[s];i;i=E[i].next)
    {   
        headx[s]=i;
        int to=E[i].to;
        int w=E[i].w;
        if(!w||deep[to]!=deep[s]+1)
        continue;
        int temp=dfs(to,t,min(w,flow-newflow));
        newflow+=temp;
        E[i].w-=temp;
        E[i^1].w+=temp;
        if(newflow==flow)
        break;
    }
    if(!newflow)deep[s]=0;
    return newflow;
}
int Dinic(int s,int t,int m)
{
    int sum=0;
    while(bfs(s,t,m))
    {   
        sum+=dfs(s,t,max);
    }
    return sum;
}
void spfa(int s)
{   
    queue<int>Q;
    for(int i=1;i<=n;i++)
    dis[i]=max;
    dis[s]=0;
    Q.push(s);
    int visit[1000];
    memset(visit,0,sizeof(visit));
    while(!Q.empty())
    {
        int k=Q.front();
        Q.pop();
        visit[k]=0;
        for(int i=heads[k];i;i=Es[i].next)
        {
            int to=Es[i].to;
            int w=Es[i].w;
            if(dis[k]+w<dis[to])
            {
                dis[to]=dis[k]+w;
                if(!visit[to])
                {
                    visit[to]=1;
                    Q.push(to);
                }
            }
        }
    }
}   
int main()
{
    int s,t;
    int a,b,c;
    int T;
    scanf("%d",&T);
    while(T--)
    {
       memset(heads,0,sizeof(heads));
       memset(head,0,sizeof(head));
       cnts=1;
       cnt=1;
       scanf("%d%d",&n,&m);
       for(int i=1;i<=m;i++)
       {
               scanf("%d%d%d",&a,&b,&c);
               ADDs(a,b,c);
               }
       scanf("%d%d",&s,&t);
       spfa(s);
        int num=0;
           for(int i=1;i<=n;i++)
           {
            for(int j=heads[i];j;j=Es[j].next)
            {    
                int w=Es[j].w;
                int to=Es[j].to;
                if(dis[to]==dis[i]+w)
                {
                    ADD(i,to,1);
                    num++;
                }
            }
        }
       printf("%d\n",Dinic(s,t,num));
       }
       return 0;
       }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值