题目链接:Sightseeing
题意:求最短路和比最短路长度+1的所有路径条数。
附代码:用数组记录最短和次短路径的长度和条数,一次更新,直到没有边可以更新。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
#define maxn 1010
struct Node {
int to, val;
Node(int to, int val) {
this->to = to;
this->val = val;
}
};// 保存每个点的所有边及其权值
vector<Node> edge[maxn];
int step[maxn][2]; //bushu[i][j] 表示i点第j短路的长度
int cnt[maxn][2]; // cnt[i][j]表示i点第j短路的条数
int main() {
int t;
scanf("%d", &t);
while(t--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
edge[i].clear();
step[i][0] = maxn*maxn;
step[i][1] = maxn*maxn;
cnt[i][0] = 0;
cnt[i][1] = 0;
}
for (int i=0; i<m; ++i) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
edge[x].push_back(Node(y, z));
}
int st, ed;
scanf("%d%d", &st, &ed);
step[st][0] = 0; // 初始化源点
step[st][1] = maxn*maxn;
cnt[st][0] = 1;
cnt[st][1] = 0;
bool ok = false;
while(1) {
ok = false;
for (int i=1; i<=n; ++i) {
for (int k=0; k<2; ++k) {
if (cnt[i][k] && i != ed) {
for (int j=0; j<edge[i].size(); ++j) {
int to = edge[i][j].to;
int val = edge[i][j].val;
if (step[to][0] > step[i][k] + val) { // 更新最短路
step[to][1] = step[to][0];
cnt[to][1] = cnt[to][0];
step[to][0] = step[i][k] + val;
cnt[to][0] = cnt[i][k];
ok = true;
}
else if (step[to][0] == step[i][k] + val) {
cnt[to][0] += cnt[i][k];
ok = true;
}
else if (step[to][1] > step[i][k] + val) { // 更新次短路
step[to][1] = step[i][k] + val;
cnt[to][1] = cnt[i][k];
ok = true;
}
else if (step[to][1] == step[i][k] + val) {
cnt[to][1] += cnt[i][k];
ok = true;
}
}
cnt[i][k] = 0;
}
}
}
if (ok == false) break;
}
// for (int i=1; i<=n; ++i) {
// cout << i << "==" << step[i][0] << " " << cnt[i][0] << " " << step[i][1] << " " << cnt[i][1] << endl;
// }
int ans = cnt[ed][0];
if (step[ed][1] == step[ed][0] + 1) {
ans += cnt[ed][1];
}
printf("%d\n", ans);
}
return 0;
}
/*
HDU 1688
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#define maxn 1010
#include <queue>
using namespace std;
struct Node {
int v, w;
Node(int v, int w) {
this->v = v;
this->w = w;
}
};
vector <Node> edge[maxn];
int st, ed;
int step[maxn][2];
int cnt[maxn][2];
int mp[maxn][maxn];
void bfs(int st) {
queue<int> que;
que.push(st);
while(!que.empty()) {
int now = que.front();
que.pop();
// cout << now << "-----------------\n";
for (int k=0; k<2; ++k) {
if (cnt[now][k] && now != ed) {
for (int j=0; j<edge[now].size(); ++j) {
int v = edge[now][j].v;
int val = edge[now][j].w;
if (step[v][0] > step[now][k] + val) {
step[v][1] = step[v][0];
cnt[v][1] = cnt[v][0];
step[v][0] = step[now][k] + val;
cnt[v][0] = cnt[now][k];
que.push(v);
// cout << v << "==1==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
}
else if (step[v][0] == step[now][k] + val) {
cnt[v][0] += cnt[now][k];
que.push(v);
// cout << v << "==2==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
}
else if (step[v][1] > step[now][k] + val) {
step[v][1] = step[now][k] + val;
cnt[v][1] = cnt[now][k];
que.push(v);
// cout << v << "==3==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
}
else if (step[v][1] == step[now][k] + val) {
cnt[v][1] += cnt[now][k];
que.push(v);
//cout << v << "==4==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
}
}
cnt[now][k] = 0;
}
}
}
}
int main() {
int t;
scanf("%d", &t);
while(t--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
edge[i].clear();
step[i][0] = maxn*maxn;
step[i][1] = maxn*maxn;
cnt[i][0] = 0;
cnt[i][1] = 0;
}
for (int i=0; i<m; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
edge[u].push_back(Node(v, w));
}
scanf("%d%d", &st, &ed);
step[st][0] = 0;
cnt[st][0] = 1;
bfs(st);
//
// for (int i=1; i<=n; ++i) {
// cout << i << "==" << step[i][0] << " " << cnt[i][0] << " " << step[i][1] << " " << cnt[i][1] << endl;
// }
int ans = cnt[ed][0];
if (step[ed][1] == step[ed][0] + 1) {
ans += cnt[ed][1];
}
printf("%d\n", ans);
}
return 0;
}
/*
99
3 3
1 2 1
2 3 1
1 3 1
1 3
*/
浙公网安备 33010602011771号