題目連結: 這裡
思路
- 注意這句:
- He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A.
- ( A , B ) 為了找存在一條從 B 出發,比『所有』從 A 出發回家的路還短,求這種路有幾條。
- 這題要尋找符合題目所敘的所有回到家裡的路徑,如果利用 Dijkstra 進行單源搜索,反過來以家裡為起點做 Dijkstra 會恰好得到我們想要的結果。
- 再來就是利用 DFS 將符合的路徑 ( dist [ $\forall$A ] < dist [ B ] ) 用一個陣列存取,就有一種 DP 的味道了。
參考資源
[CSDN] UVA 10917 Walk Through the Forest 迪杰斯特拉+记忆化搜索
AC 原始碼
#pragma GCC optimize ("O2")
#include<bits/stdc++.h>
#pragma region define/typedef
/*-----define-----*/
#define jizz ios_base::sync_with_stdio(false),cin.tie(NULL)
#define ALL(X) (X).begin(), (X).end()
#define REP(I,N) for(int I=0;I<(N);I++)
#define REP1(I,N,M) for(int I=(N);I<(M);I++)
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(), c.end(),x)-c.begin())
#define MS0(X) memset((X), 0, sizeof((X)))
#define maxE(x) (*max_element((x).begin(), (x).end()))
#define minE(x) (*min_element((x).begin(), (x).end()))
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
/*-----typedef-----*/
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
#pragma endregion
VPII adj[1005];
int dist[1005], dp[1005];
priority_queue<PII,vector<PII>,greater<PII>> pq;
void init(void) {
memset(dist, INF, sizeof(dist));
REP(i, 1005) dp[i] = -1, adj[i].clear();
}
void dijkstra(void) {
int vis[1005] = {0};
dist[2] = 0; //從終點做單源最短有利於從其他點求到終點最短路
pq.emplace(make_pair(dist[2], 2));
while(!pq.empty()) {
PII now = pq.top();
pq.pop();
//if(dist[now.first]!=now.second) continue;
if(vis[now.second]) continue;
vis[now.second] = 1;
int now_node = now.second;
for(auto i : adj[now_node]) { //i.first: 點 i.second: 權重
if(dist[i.first] > dist[now_node] + i.second) {
dist[i.first] = dist[now_node] + i.second;
pq.emplace(make_pair(dist[i.first], i.first));
}
}
}
}
int dfs(int idx) {
int sum = 0;
if(dp[idx] != -1) return dp[idx];
if(idx == 2) return 1;
// 為了找存在一條從 B 出發,比『所有』從 A 出發回家的路還短,求這種路有幾條。
for(auto i : adj[idx]) if(dist[i.first] < dist[idx]) sum += dfs(i.first);
return dp[idx] = sum;
}
signed main() {
jizz;
#ifndef ONLINE_JUDGE
freopen("output.txt", "w", stdout);
freopen("input.txt", "r", stdin);
#endif
int n, m, a, b, w;
while(cin >> n && n != 0) {
init();
cin >> m;
REP(i, m) {
cin >> a >> b >> w;
adj[a].emplace_back(make_pair(b, w));
adj[b].emplace_back(make_pair(a, w));
}
dijkstra();
cout << dfs(1) << "\n";
}
return 0;
}
- 本文連結:https://blog.subarya.me/2021/08/16/Uva10917%20-%20Walk%20Through%20the%20Forest/
- 版權聲明:本Blog所有文章除了特別聲明外,均默認採用 許可之協議。