2017多校第10場 HDU 6181 Two Paths 次短路
阿新 • • 發佈:2017-08-27
-1 pat sca new tin add str clu operator
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6181
題意:給一個圖,求出次短路。
解法:我之前的模板不能解決這種圖,就是最短路和次短路相等的情況,證明這題數據還是水了。下來我修改了一下次短路的,就可以避免這種情況了。提供一個sample 4 4
(1,2,1)( 1, 3,1) (2 4,1) (3 ,4,1)。這組的正確答案是2,算法就來看代碼吧。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL maxn = 100010; LL n, m; LL ST, EN; LL num, pos[maxn]; LL vis[maxn][2]; LL cnt[maxn][2], dis[maxn][2]; struct node1 { LL en, val, next; node1(LL en = 0, LL val = 0, LL next = 0): en(en), val(val), next(next) {} } E[maxn * 2]; struct node { LL id; LL val; LL flag; //最短/次短 node(LL id = 0, LL val = 0, LL flag = 0): id(id), val(val), flag(flag) {} friend bool operator <(node x, node y) { return x.val > y.val; } }; void add(LL st, LL en, LL val) { E[num] = node1(en, val, pos[st]); pos[st] = num++; } void dij() { dis[ST][0] = 0; cnt[ST][0] = 1; priority_queue<node>q; q.push(node(ST, 0, 0)); while (!q.empty()) { node now = q.top(); q.pop(); LL val = now.val; LL u = now.id ; LL flag = now.flag; if (vis[u][flag]) continue; vis[u][flag] = 1; for (LL i = pos[u]; i != -1; i = E[i].next) { LL v = E[i].en; LL newlen = val + E[i].val; if (newlen <= dis[v][0]) //新路徑比原最短路更小 { if (dis[v][0] != INF) //如果當前點的最短路曾更新過 { //那麽不僅更新最短,也要更新次短 dis[v][1] = dis[v][0]; cnt[v][1] = cnt[v][0]; //次短路條數等於原來的最短路條數 q.push(node(v, dis[v][1], 1)); //入隊,當前點距離更新,之後的也會更新 } dis[v][0] = newlen; //否則僅更新最短路 cnt[v][0] = cnt[u][flag]; //更新最短路條數,最短路條數由u點得到,u點狀態由flag標記 q.push(node(v, newlen, 0)); } else if (newlen == dis[v][0]) cnt[v][0] += cnt[u][flag]; //增加最短路條數 else if (newlen == dis[v][1]) cnt[v][1] += cnt[u][flag]; //增加次短路條數 else if (newlen < dis[v][1]) //新路徑大於最短路,但是小於次短路,更新次短路 { dis[v][1] = newlen; cnt[v][1] = cnt[u][flag]; //次短路條數由u點得 q.push(node(v, dis[v][1], 1)); } } } } void init() { num = 0; memset(cnt, 0, sizeof(cnt)); memset(vis, 0, sizeof(vis)); memset(E, 0, sizeof(E)); memset(pos, -1, sizeof(pos)); memset(dis, 0x3f, sizeof(dis)); } int main() { LL T; scanf("%lld", &T); while(T--) { init(); scanf("%lld %lld", &n,&m); while(m--){ LL u, v, w; scanf("%lld%lld%lld", &u,&v,&w); add(u, v, w); add(v, u, w); } ST = 1; EN = n; dij(); printf("%lld\n", dis[EN][1]); } return 0; }
2017多校第10場 HDU 6181 Two Paths 次短路