hdu-3416-Marriage Match IV-(求最小割)-网络流模板

2 篇文章 0 订阅
1 篇文章 0 订阅

Marriage Match IV

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


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


题目大意:给你一个图,问你起点到终点有多少条最短路径。选了其中一条路径这条路径的所有走过的边都不能再走。

思路:先一遍dij求出起点到所有点的最短路,然后把所有在最短路里面的边都保存下来,构造一个新图,建一个源点在起点汇点在终点的图,求出这个图的最小割,就是最后的答案了。

#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#define lson l,mid,o<<1
#define rson mid + 1,r ,o<<1|1
using namespace std;
const int maxn = 20005;
int ma = 2011111111;
struct Edge
{
    int v,next,w;
}e[maxn * 20];
int a[maxn],head[maxn],cnt,n,m,edge[maxn * 20][3],ed;
void add(int a,int b,int c)
{
    e[cnt].v = b;
    e[cnt].w = c;
    e[cnt].next = head[a];
    head[a] = cnt++;
}
void init()
{
    memset(head,-1,sizeof(head));
    cnt = 0;
}
int d[maxn],vis[maxn];
struct node
{
    int vis,val;
    node(){};
    node(int a,int b)
    {
        vis = a;val = b;
    }
    friend bool operator <(node a,node b)
    {
        return a.val > b.val;
    }
};
void dij(int st)
{
    int i;
    for(i = 1; i <= n; i++)
    {
        d[i] = ma;
    }
    d[st] = 0;
    memset(vis,0,sizeof(vis));
    priority_queue<node> q;
    q.push(node(st,0));
    while(!q.empty())
    {
        node w = q.top();
        q.pop();
        int begin = w.vis;
        if(vis[begin] == 1)
            continue;
        vis[begin] = 1;
        for(i = head[begin]; i != -1; i = e[i].next)
        {
            int end = e[i].v;
            if(d[end] > d[begin] + e[i].w)
            {
                d[end] = d[begin] + e[i].w;
                q.push(node(end,d[end]));
            }
        }
    }
}
int used[2050];
int INF = 2100000000;
int level[2050];
void bfs(int u,int vv)
{
    memset(level,0,sizeof(level));
    int pre[10005];
    int begin = 0,end = 1;
    pre[0] = u;
    level[u] = 0;
    while(begin < end)
    {
        int i;
        if(level[vv] != 0)
            return;
        int st = pre[begin];
        for(i = head[st]; i != -1;i = e[i].next)
        {
            int v = e[i].v;
            if(e[i].w == 0)
            continue;
            if(level[v] == 0)
            {
                level[v] = level[st] + 1;
                pre[end++] = v;
                if(v == vv)
                    return;
            }
        }
        begin++;
    }
}
int dfs(int u,int t,int c)
{
    if(c == 0||u == t)
    {
        return c;
    }
    used[u] = 1;
    int i;
    int flow = 0;
    for(i = head[u]; i != -1; i = e[i].next)
    {
        int end = e[i].v;
        if(used[end])
            continue;
        if(level[end] > level[t])
            continue;
        int f = dfs(end,t,min(e[i].w,c));
        if(f > 0)
        {
            flow += f;
            e[i].w -= f;
            e[i ^ 1].w += f;
            c -= f;
            if(c == 0)
                break;
        }
    }
    return flow;
}
int f(int u,int v)//u是源点,v是汇点
{
    int flow = 0;
    for(;;)
    {
        memset(used,0,sizeof(used));
        bfs(u,v);
        if(level[v] == 0)
            return flow;
        int f = dfs(u,v,INF);
        flow += f;
    }
    return flow;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d %d",&n,&m);
        int st;
        int i,j;
        for(i = 0; i < m; i++)
        {
            int q,w,e1;
            scanf("%d %d %d",&q,&w,&e1);
            edge[i][0] = q;
            edge[i][1] = w;
            edge[i][2] = e1;
            if(q == w)
                continue;
            add(q,w,e1);
        }
        scanf("%d %d",&st,&ed);
        dij(st);
        if(d[ed] == ma)
        {
            printf("0\n");
            continue;
        }
        init();
        for(i = 0; i < m; i++)
        {
            if(edge[i][0] == edge[i][1])
                continue;
            if(d[edge[i][0]] + edge[i][2] == d[edge[i][1]])
            {

                add(edge[i][0],edge[i][1],1);
                add(edge[i][1],edge[i][0],0);
            }
        }
        printf("%d\n",f(st,ed));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值