日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【spfa】假期计划(jzoj 3936)

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【spfa】假期计划(jzoj 3936) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

假期計劃

jzoj 3936

題目大意

給你一個有向圖(n,m?20000n,m\leqslant 20000n,m?20000),現在有一些作為樞紐的點,且保證每一條邊的兩個點至少有一個是樞紐點,現在給q個詢問,問某一個點到另一個點的最短路,你只需輸出可以到達的數量,和可以到達的最短路之和

輸入樣例

3 3 1 2 1 2 10 2 3 10 2 1 5 2 1 3 3 1

輸出樣例

1 20

數據范圍

對于 30%的數據,N?100,M?2,000。N\leqslant 100,M\leqslant 2,000。N?100M?2,000。
對于 100%的數據,1?N,M?20,000,1?K?200,1?Q?50,000,1?di?10,000。1\leqslant N,M\leqslant 20,000,1\leqslant K\leqslant 200,1\leqslant Q\leqslant 50,000, 1\leqslant d_i\leqslant 10,000。1?N,M?20,0001?K?2001?Q?50,0001?di??10,000

樣例說明

對于第一個航班,唯一可行的路線是1?>2?>31->2->31?>2?>3,花費 20。

解題思路

因為樞紐點很少,我們對于每一個樞紐點跑一邊spfaspfaspfa
如果詢問的出發點是樞紐點,那就是直接最短路的值
如果不是,那和他相連的就都是,然后計算這條邊加和他相連的點到終點的最短路就是結果

代碼

#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; ll n, m, k, q, x, y, z, tot, num, sum, ans, p[20010], v[20010], head[20010], b[210][20010]; struct rec {ll to, l, next; }a[20010]; void spfa(ll x) {memset(b[v[x]], 127/3, sizeof(b[v[x]]));b[v[x]][x] = 0;//以第x個樞紐為起點到各個點的最短路p[x] = 1;queue<ll>d;d.push(x);while(!d.empty()){ll h = d.front();d.pop();for (ll i = head[h]; i; i = a[i].next)if (b[v[x]][h] + a[i].l < b[v[x]][a[i].to]){b[v[x]][a[i].to] = b[v[x]][h] + a[i].l;if (!p[a[i].to]){p[a[i].to] = 1;d.push(a[i].to);}}p[h] = 0;} } int main() {scanf("%lld%lld%lld%lld", &n, &m, &k, &q);for (ll i = 1; i <= m; ++i){scanf("%lld%lld%lld", &x, &y, &z);a[++tot].to = y;a[tot].l = z;a[tot].next = head[x];head[x] = tot;}for (ll i = 1; i <= k; ++i){scanf("%lld", &x);v[x] = i;//記錄下他是第幾個,方便減小內存spfa(x);}for (ll i = 1; i <= q; ++i){scanf("%lld%lld", &x, &y);sum = 200000010;if (v[x]) sum = min(sum, b[v[x]][y]);//他就是樞紐for (ll j = head[x]; j; j = a[j].next)if (v[a[j].to])sum = min(sum, a[j].l + b[v[a[j].to]][y]);//相連的樞紐if (sum <= 200000000){num++;ans += sum;}}printf("%lld\n%lld", num ,ans);return 0; }

總結

以上是生活随笔為你收集整理的【spfa】假期计划(jzoj 3936)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。