题目描述
人类和人鱼拥有共同的祖先,因为某种原因发生了分化,人鱼到了大海里生活。近年来人类对大海及生态的破坏,人鱼族的生存环境受到了严重的影响。最近某地产公司筹备一个填海计划,在附近的大海中装入了声呐系统,这极大地限制了人鱼的活动。
人鱼族的居民们为了适应环境,建立了n个聚居点(从1到n编号),m条有一定长度的单向通道,每条由一个聚居点通向另一个聚居点。人鱼族派出了美人鱼珊珊去勾引地产公司的老总刘轩,来逼迫他关闭声呐系统。现在珊珊在S号点,她要到T号点,然后通过T号点到达陆地上。她当然希望自己能走最短的路来从S到达T,不过比最短路长1的路径,她也是可以接受的。她想知道从S到T的最短路和比最短路长1的路径一共有多少条。
输入
输入数据共m+2行。
第一行两个数n,m,含义如题目所述。(1<=n<=1000,1<=m<=15000)
第2到m+1行,共m行,每行3个数a[i],b[i],c[i],表示从a[i]到b[i]有一条长度为c[i]的通道(1<=a[i],b[i]<=n,1<=c[i]<=10000,可能有重边)。
第m+2行两个数S,T,含义如题目所述。
输出
输出一个数,表示从S到T的最短路和比最短路长1的路径的数目。
#include<iostream>
#define max 10001
using namespace std;
struct edg {
int w;
int to;
int next;
};
class G {
private:
edg *edgs;
int dis[50][2][2];
int n, m, S, T, num;
bool isar[50][2];
void path() {
int l, i, j, v, min, k, len;
dis[S][0][0] = 0;
for (l = 0; l < 2 * n; l++) {
v = -1;
min = max;
for (j = 0; j < n; j++) {
if (!isar[j][0] && dis[j][0][0] < min) {
min = dis[j][0][0];
v = j;
k = 0;
}
else if (!isar[j][1] && dis[j][1][0] < min) {
min = dis[j][1][0];
v = j;
k = 1;
}
}
if (v == -1)
break;
isar[v][k] = true;
for (j = v; edgs[j].next != -1; j = edgs[j].next) {
len = edgs[j].w;
i = edgs[j].to;
len = len + dis[v][k][0];
if (len < dis[i][0][0]) {
dis[i][1][0] = dis[i][0][0];
dis[i][1][1] = dis[i][0][1];
dis[i][0][0] = len;
dis[i][0][1] = dis[v][k][1];
}
else if (len == dis[i][0][0]) {
dis[i][0][1] += dis[v][k][1];
}
else if (len < dis[i][1][0]) {
dis[i][1][0] = len;
dis[i][1][1] = dis[v][k][1];
}
else if (len == dis[i][1][0]) {
dis[i][1][1] += dis[v][k][1];
}
}
}
}
public:
G(int m, int n) {
int i, j, x, y, l;
num = n;
this->m = m;
this->n = n;
edgs = new edg[m + n];
for (i = 0; i < n; i++) {
edgs[i].next = -1;
}
for (i = 0; i < m; i++) {
cin >> x >> y >> l;
x--, y--;
j = x;
while (edgs[j].next != -1) {
j = edgs[j].next;
}
edgs[j].to = y;
edgs[j].w = l;
edgs[j].next = num;
edgs[num++].next = -1;
dis[i][0][0] = dis[i][1][0] = max;
dis[i][0][1] = dis[i][1][1] = 1;
isar[i][0] = isar[i][1] = false;
}
cin >> S >> T;
S--, T--;
}
void ans() {
path();
if (dis[T][0][0] + 1 == dis[T][1][0]) {
cout << dis[T][0][1] + dis[T][1][1] << endl;
}
else
cout << dis[T][0][1] << endl;
}
};
int main()
{
int m, n;
while (cin >> n >> m) {
G *g = new G(m, n);
(*g).ans();
delete g;
}
return 0;
}