题目链接: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 */