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?
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.
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有多少条不同的最短路,什么叫做不同的最短路呢,就是任意两条最短路上都没有相同的边,因为是最短路嘛,所以每一条的距离都是相同的、最短的。
这样我们就可以把只要在任意一条最短路上的边加到网络里,然后跑一波最大流,最大的流量就是要求的答案。
那么怎么找到所有最短路上的边呢,我们可以从起点和终点分别跑一次最短路,用dis1[i]表示用起点到i点的最短距离,用dis2[i]表示从终点到i点的最短距离(这里的dis2是反向建边求出的最短距离),那么对于一条边(x,y,z),如果dis1[x] + dis2[y] + z == dis1[B],那么这条边就肯定是某一条最短路上的边。
边建好了就可以跑最大流了。
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1100;
const int inf = 1e8;
struct edge
{
int from, to, cap, flow;
};
struct dinic
{
int n,m,s,t;
vector<edge> edges;
vector<int> g[maxn];
bool b[maxn];
int dis[maxn];
int cur[maxn];
void initial(int n)
{
for(int i=0;i<=n;i++)
g[i].clear();
edges.clear();
}
void addedge(int from,int to,int cap)
{
edges.push_back((edge){from,to,cap,0});
edges.push_back((edge){to,from,0,0});
m = edges.size();
g[from].push_back(m-2);
g[to].push_back(m-1);
}
bool bfs()
{
memset(b,0,sizeof(b));
queue<int> q;
q.push(s);
b[s] = 1;
dis[s] = 0;
while(!q.empty())
{
int x = q.front();
q.pop();
for(int i=0;i<g[x].size();i++)
{
edge &e = edges[g[x][i]];
if(!b[e.to] && e.cap > e.flow)
{
b[e.to] = 1;
dis[e.to] = dis[x] + 1;
q.push(e.to);
}
}
}
return b[t];
}
int dfs(int x,int a)
{
if(x == t || a == 0)
return a;
int flow = 0,f;
for(int& i = cur[x];i<g[x].size();i++)
{
edge& e = edges[g[x][i]];
if(dis[x] + 1 == dis[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow)))>0)
{
e.flow += f;
edges[g[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0)
break;
}
}
return flow;
}
int maxflow(int s ,int t)
{
int flow = 0;
while(bfs())
{
memset(cur,0,sizeof(cur));
flow += dfs(s,inf);
}
return flow;
}
}DC;
struct Edge
{
int to,cost;
Edge(int a,int b)
{
to = a;
cost = b;
}
friend bool operator <(Edge a,Edge b)
{
return a.cost > b.cost;
}
};
int n,m;
int dis1[maxn],dis2[maxn];
vector<Edge> e1[maxn];
vector<Edge> e2[maxn];
void dj(int s,vector<Edge> *e,int *dis)
{
int i,j;
priority_queue<Edge> q;
for(i=1;i<=n;i++)
dis[i] = inf;
dis[s] = 0;
q.push(Edge(s,0));
while(!q.empty())
{
Edge t = q.top();
q.pop();
for(i=0;i<e[t.to].size();i++)
{
Edge es = e[t.to][i];
if(dis[es.to] > dis[t.to] + es.cost)
{
dis[es.to] = dis[t.to] + es.cost;
q.push(Edge(es.to,dis[es.to]));
}
}
}
}
int main(void)
{
int T,i,j,A,B;
scanf("%d",&T);
DC.s = 0;
while(T--)
{
scanf("%d%d",&n,&m);
DC.t = n+1;
DC.initial(DC.t);
for(i=1;i<=n;i++)
{
e1[i].clear();
e2[i].clear();
}
for(i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(x == y)
continue;
e1[x].push_back(Edge(y,z));
e2[y].push_back(Edge(x,z));
}
scanf("%d%d",&A,&B);
dj(A,e1,dis1);
dj(B,e2,dis2);
DC.addedge(DC.s,A,inf);
for(i=1;i<=n;i++)
{
for(j=0;j<e1[i].size();j++)
{
int t = e1[i][j].to;
if(dis1[i] + dis2[t] + e1[i][j].cost == dis1[B])
{
DC.addedge(i,t,1);
}
}
}
DC.addedge(B,DC.t,inf);
int ans = DC.maxflow(DC.s,DC.t);
cout << ans << endl;
}
return 0;
}