HDU 3416 Marriage Match IV 最短路跑路径 + 最大流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tawn0000/article/details/82830586

                                          Marriage Match IV

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


 

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

只要懂题目意思就可以敲了,题目要求找出A-B最短路径有多少条

所以只要 跑A-B 的最短路和B-A的最短路,保留有效边跑最大流,容量为1.

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3+10;
const int maxm = 1e5+10;
const int mod = 1e9+7;

#define sc(x)  scanf("%d",&x)
#define pfn(x) printf("%d\n",x)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb(x)  push_back(x)

int h[maxn];
int l[maxn];
int cur[maxn];
int n,m;
int tot = 0;

struct edge
{
  int to,c,next;
  edge(int to = 0, int c = 0, int next = 0) : to(to), c(c), next(next) {}
}es[maxm*2];

void add_edge(int u, int v, int c)
{
  es[tot] = edge(v,c,h[u]);
  h[u] = tot++;
}

bool bfs(int s, int t)
{
  mem(l,0);
  l[s] = 1;
  queue <int> q;
  q.push(s);
  while(!q.empty())
  {
    int u = q.front();
    q.pop();
    if(u == t) return true;
    for(int i = h[u]; i != -1; i = es[i].next)
    {
      if(es[i].c && !l[es[i].to])
      {
        l[es[i].to] = l[u] + 1;
        q.push(es[i].to);
      }
    }
  }
  return false;
}


int dfs(int x, int t, int mf)
{
  if(x == t) return mf;
  int ret = 0;
  for(int &i = cur[x]; i != -1; i = es[i].next)
  {
    if(es[i].c && l[x] == l[es[i].to] -1)
    {
      int f = dfs(es[i].to,t,min(es[i].c,mf-ret));
      es[i].c -= f;
      es[i^1].c += f;
      ret += f;
      if(ret == mf) return  ret;
    }
  }
  return ret;
}

int dinic(int s, int t)
{
  int res = 0;
  while(bfs(s,t))
  {
    //cout << "*" << endl;
    for(int i = 1; i <= n; i++) cur[i] = h[i];
    res += dfs(s,t,INF);
    //cout << res;
  }
  return res;
}


int ds[maxn];
int dt[maxn];
vector <edge> Gs[maxn];
vector <edge> Gt[maxn];

void dijkstra(int s, int t)
{
  mem(ds,INF);
  priority_queue <P> Q;
  ds[s] = 0;
  Q.push(P(0,s));
  while(!Q.empty())
  {
    P p = Q.top();
    Q.pop();
    int u = p.second;
    if(ds[u] < p.first) continue;
    for(int i = 0; i < Gs[u].size(); i++)
         {
          edge e = Gs[u][i];
          if(ds[e.to] > ds[u] + e.c)
          {
            ds[e.to] = ds[u] + e.c;
            Q.push(P(ds[e.to],e.to));
          }
         }
  }

  mem(dt,INF);
  dt[t] = 0;
  Q.push(P(0,t));
  while(!Q.empty())
  {
    P p = Q.top();
    Q.pop();
    int u = p.second;
    if(dt[u] < p.first) continue;
    for(int i = 0; i < Gt[u].size(); i++)
         {
          edge e = Gt[u][i];
          if(dt[e.to] > dt[u] + e.c)
          {
            dt[e.to] = dt[u] + e.c;
            Q.push(P(dt[e.to],e.to));
          }
         }
  }
}

int main()
{
   int T;
   sc(T);
   while(T--)
   {
      tot = 0;
      sc(n);sc(m);
      for(int i = 1; i <= n; i++) {Gs[i].clear();Gt[i].clear();}
      for(int i = 0; i < m; i++)
      {
        int a,b,c;
        sc(a);sc(b);sc(c);
        if(a == b) continue;
        Gs[a].pb(edge(b,c));
        Gt[b].pb(edge(a,c));
      }
      int s,t;
      sc(s);sc(t);
      dijkstra(s,t);
      mem(h,-1);
      for(int i = 1; i <= n; i++)
      {
        for(int j = 0; j < Gs[i].size(); j++)
          {
            edge e = Gs[i][j];
            if(ds[t] == ds[i] + dt[e.to] + e.c)
            {
              //cout << i << e.to << endl;
              add_edge(i,e.to,1);
              add_edge(e.to,i,0);
            }
          }
      }
      //cout << ds[t] << " " << dt[s] << endl;
      //cout << "*" << endl;
    int ans = dinic(s,t);
    pfn(ans);
  }
   return 0;
}

猜你喜欢

转载自blog.csdn.net/Tawn0000/article/details/82830586
今日推荐