【hduoj 3416 】Marriage Match IV 【最小割dinic+最短路spfa】

来源:互联网 发布:淘宝客服规则 编辑:程序博客网 时间:2024/06/01 09:00

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, 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

题意 给n给点,m条边,问一共有几个最短路从A到B。

分析 ,跑一遍最短路spfa,然后以最短路中的边,重建图,边权为1。然后再新图上最大流得到最小割。

来讲一下我的想法,为什么建新图之后,在跑最大流就可以得到答案;

首先题目要求有多少个 距离相等但是路径不同的最短路,我们把最短路剖出来,然后建立边权为1的新图,跑最大流,因为边权都是1,所以最大流的含义就可以理解为 有几个不同的路径到终点【稍微想一下就知道了】 。
代码

#include<bits/stdc++.h>using namespace std;#define LL long long const int MAXN =1000+10;const int MAXM =1e6;const int inf = 0x3f3f3f3f;/*---------------------*/struct Ee{    int from,to,val,nexts;}ee[MAXM];int hd[MAXN],tp;int n,m;int S,T;void It(){    memset(hd,-1,sizeof(hd));    tp=0;}void addee(int a,int b,int c){ // 其实不管重边 也是可以的,而且速度更快 ⊙﹏⊙b汗      for(int i=hd[a];i!=-1;i=ee[i].nexts){// 是有重边,但是是不能把重边全删除只保留最小重边。        Ee& e=ee[i];        if(e.to==b){            if(c<e.val){  e.val=c; return ;}// 如果有小的肯定要取最小的            else if(c>e.val) return ;//大于肯定不要             break;//但是如果相等的话,必须要,如果这个边是在最短路中的话,就是双倍的答案。        }    }    Ee e={a,b,c,hd[a]};    ee[tp]=e;hd[a]=tp++;}void input(){    int a,b,c;    while(m--){        scanf("%d%d%d",&a,&b,&c);        if(a==b) continue;        addee(a,b,c);    }}int vis[MAXN],dis[MAXN];void spfa(int st,int ed){    memset(vis,0,sizeof(vis));    memset(dis,0x3f,sizeof(dis));//一开始居然把这里赋值为-1,找了半天TAT    vis[st]=1;dis[st]=0;    queue<int>Q;Q.push(st);    while(!Q.empty()){        int now=Q.front();Q.pop();vis[now]=0;        for(int i=hd[now];i!=-1;i=ee[i].nexts){            Ee e=ee[i];            if(dis[e.to]>dis[now]+e.val){                dis[e.to]=dis[now]+e.val;                if(!vis[e.to]){                    vis[e.to]=1;                    Q.push(e.to);                }            }        }       }}struct Edge {    int from,to,cap,flow,nexts;}edge[MAXM];int head[MAXN],top;int cur[MAXN];void init(){    memset(head,-1,sizeof(head));    top=0;}void addedge(int a,int b,int c){    Edge e={a,b,c,0,head[a]};    edge[top]=e;head[a]=top++;    Edge ee={b,a,0,0,head[b]};    edge[top]=ee;head[b]=top++;}void getmap(){// 这个建图的方式很好      for(int now=1;now<=n;now++){        for(int i=hd[now];i!=-1;i=ee[i].nexts){            Ee e=ee[i];            if(dis[e.to]==dis[now]+e.val){                addedge(now,e.to,1);            }         }    }} bool bfs(int st,int ed){    memset(vis,0,sizeof(vis));    queue<int>Q; Q.push(st);    vis[st]=1;dis[st]=1;    while(!Q.empty()){        int now=Q.front();Q.pop();        for(int i=head[now];i!=-1;i=edge[i].nexts){            Edge e=edge[i];            if(!vis[e.to]&&e.cap-e.flow>0){                vis[e.to]=1;                dis[e.to]=dis[now]+1;                if(e.to==ed)  return 1;                Q.push(e.to);            }        }     }    return 0;}int dfs(int now,int a,int ed){    if(now==ed||a==0) return a;    int flow=0,f;    for(int& i=cur[now];i!=-1;i=edge[i].nexts){        Edge &e=edge[i];        if(dis[e.to]==dis[now]+1&&(f=dfs(e.to,min(a,e.cap-e.flow),ed))>0){            e.flow+=f;            flow+=f;            edge[i^1].flow-=f;            a-=f;            if(a==0) break;        }    }    return flow;}int max_flow(int st,int ed){    int flow=0;    while(bfs(st,ed)){        memcpy(cur,head,sizeof(head));        flow+=dfs(st,inf,ed);    }     return flow;}int main(){    int t;cin>>t;    while(t--){        scanf("%d%d",&n,&m);        It();        input();        scanf("%d%d",&S,&T);        spfa(S,T);        init();        getmap();        printf("%d\n",max_flow(S,T));      }    return 0;}
阅读全文
0 0
原创粉丝点击