pat 1003 Emergency
阿新 • • 發佈:2021-01-20
題目連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376
- 要看清楚到底是有向圖還是無向圖(建圖的時候要用)
- 用哪種方法求最短路
- 仔細考慮附帶問題(像本題中的最短路的個數,和在最短路條件下的最大營救人數)
#include <iostream> #include <cstdio> #include <queue> using namespace std; struct edge{ int u,v,w,next; }e[1100]; int team[505], head[505], cnt, sum[505]; //c1-i最短路徑下的team數 int n,m,c1,c2, dis[505]; int path_num[505]; bool vis[505]; void add(int a, int b, int c){//鄰接表存圖 e[++cnt].u = a; e[cnt].v = b; e[cnt].w = c; e[cnt].next = head[a]; head[a] = cnt; } void dijkstra(){ //優先佇列優化的dijkstra演算法 for (int i = 0; i < n; i++){ dis[i] = 1e9; vis[i] = false; } dis[c1] = 0; sum[c1] = team[c1]; path_num[c1] = 1; priority_queue<pair<int,int> > que; que.push(make_pair(0, c1)); while (!que.empty()){ int cur = que.top().second; //cout<<cur<<endl; que.pop(); if (vis[cur]) continue; vis[cur] = true; for (int i = head[cur]; i; i = e[i].next){ int now = e[i].v; if (vis[now]) continue; if (dis[cur]+e[i].w < dis[now]){ dis[now] = dis[cur] + e[i].w; que.push(make_pair(-dis[now], now)); path_num[now] = path_num[cur];//如果最短路更新,那麼path_num和sum都要重新賦值 sum[now] = sum[cur]+team[now]; }else if (dis[cur]+e[i].w == dis[now]){ path_num[now] += path_num[cur]; sum[now] = max(sum[now], sum[cur]+team[now]); } } } } int main() { cin>>n>>m>>c1>>c2; for (int i = 0; i < n; i++) cin >> team[i]; for (int i = 0; i < m; i++){ int a,b,c; cin>>a>>b>>c; add(a, b, c); add(b, a, c); //這裡要進行雙邊儲存、又因為是雙向建邊,因為edge要開點的兩倍多一點 } dijkstra(); cout<<path_num[c2]<<" "<<sum[c2]; return 0; }