hdu 6181 Two Paths -最短路条数+次短路 - 多校联盟10
2017-08-24 17:48
417 查看
Two Paths
[b]Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 153428/153428 K (Java/Others)Total Submission(s): 37 Accepted Submission(s): 24
[/b]
[align=left]Problem Description[/align]You are given a undirected graph with n nodes (numbered from 1 to n) and m edges. Alice and Bob are now trying to play a game.
Both of them will take different route from 1 to n (not necessary simple).
Alice always moves first and she is so clever that take one of the shortest path from 1 to n.
Now is the Bob's turn. Help Bob to take possible shortest route from 1 to n.
There's neither multiple edges nor self-loops.
Two paths S and T are considered different if and only if there is an integer i, so that the i-th edge of S is not the same as the i-th edge of T or one of them doesn't exist.
[align=left]Input[/align]The first line of input contains an integer T(1 <= T <= 15), the number of test cases.
The first line of each test case contains 2 integers n, m (2 <= n, m <= 100000), number of nodes and number of edges. Each of the next m lines contains 3 integers a, b, w (1 <= a, b <= n, 1 <= w <= 1000000000), this means that there's an edge between node a and node b and its length is w.
It is guaranteed that there is at least one path from 1 to n.
Sum of n over all test cases is less than 250000 and sum of m over all test cases is less than 350000.
[align=left]Output[/align]For each test case print length of valid shortest path in one line.
[align=left]Sample Input[/align]2
3 3
1 2 1
2 3 4
1 3 3
2 1
1 2 1
[align=left]Sample Output[/align]5
3
Hint
For testcase 1, Alice take path 1 - 3 and its length is 3, and then Bob will take path 1 - 2 - 3 and its length is 5.
For testcase 2, Bob will take route 1 - 2 - 1 - 2 and its length is 3
[align=left]Source[/align]2017 Multi-University Training Contest - Team 10
代码:整合版
/* 题意: n点m条边的无向图,第一个人走最短路, 第二个人在满足走和第一个人不同的路(只要其中一个边不同就行)的条件下 路径最短是多少 解题思路: 如果图中存在多条最短路,那么输出最短路用的时间否则输出次短路用的时间 最短路条数: 当dist[v]+e.cost < dist[e.to]时,最短路只能从v走到e.to,所以cnt[e.to] = cnt[v]; 当dist[v]+e.cost = dist[e.to]时,最短路可以从v走到e.to,所以cnt[e.to] += cnt[v]; 次短路: 到顶点v的次短路要么是最短路dist[u]+G[u][v],要么是次短路dist2[u]+G[u][v], 所以求出每个点的最短路和次短路,最后与dijkstra做法相同不断更新这两个距离 */ #include <cstring> #include <cstdio> #include <iostream> #include <vector> #include <queue> #include <algorithm> #include <utility> #define INF 0x3f3f3f3f using namespace std; typedef unsigned long long ll; typedef pair<ll,ll> P; const int maxn=100000+10; ll n,r;//n个点,r条边 ll dist[maxn]; ll dist2[maxn]; struct edge { ll to; ll cost; }; vector<edge> G[maxn]; ll cnt[maxn]; void solve(){ ///次短路和最短路整合 priority_queue<P,vector<P>,greater<P> > que; memset(dist,INF,sizeof(dist)); memset(dist2,INF,sizeof(dist2)); memset(cnt, 0, sizeof(cnt)); cnt[0] = 1; dist[0] = 0; que.push(P(0,0) ); while(!que.empty()){ P p = que.top(); que.pop(); ll v = p.second; ll d = p.first; if(dist2[v] < d) continue; for(ll i = 0;i<G[v].size();++i){ edge &e = G[v][i]; ll d2 = d+e.cost; if(dist[e.to] > d2){ swap(dist[e.to],d2); cnt[e.to] = cnt[v]; que.push(P(dist[e.to],e.to)); }else if (d2 == dist[e.to]){///d2等价于dist[v]+ e.cost if(!(dist[v] < d)) ///避免使用未更新过的值重复加,并且if(dist[v] < d) continue;不可放到61行会影响dist2取值 cnt[e.to] += cnt[v]; } if(dist2[e.to] > d2 && dist[e.to] < d2){///保证将更新的次短路的值是大于最短路的 dist2[e.to] = d2; que.push(P(dist2[e.to],e.to)); } } } if (cnt[n-1] > 1){ cout << dist[n-1] << endl; return; } printf("%lld\n",dist2[n-1]); } int main() { int t; scanf("%d",&t); while(t--){ //初始化map for(ll i = 0;i<maxn;++i) G[i].clear(); scanf("%d%d",&n,&r); for(ll i=0;i<r;++i) { edge temp,temp1; ll u,v; ll w; scanf("%lld%lld%lld",&u,&v,&w); temp.to = v-1; temp.cost = w; temp1.to =u-1; temp1.cost=w; G[u-1].push_back(temp); G[v-1].push_back(temp1); } solve(); } return 0; }代码:分开版
/* 题意: n点m条边的无向图,第一个人走最短路, 第二个人在满足走和第一个人不同的路(只要其中一个边不同就行)的条件下 路径最短是多少 解题思路: 如果图中存在多条最短路,那么输出最短路用的时间否则输出次短路用的时间 最短路条数: 当dist[v]+e.cost < dist[e.to]时,最短路只能从v走到e.to,所以cnt[e.to] = cnt[v]; 当dist[v]+e.cost = dist[e.to]时,最短路可以从v走到e.to,所以cnt[e.to] += cnt[v]; 次短路: 到顶点v的次短路要么是最短路dist[u]+G[u][v],要么是次短路dist2[u]+G[u][v], 所以求出每个点的最短路和次短路,最后与dijkstra做法相同不断更新这两个距离 */ #include <cstring> #include <cstdio> #include <iostream> #include <vector> #include <queue> #include <algorithm> #include <utility> #define INF 0x3f3f3f3f using namespace std; typedef unsigned long long ll; typedef pair<ll,ll> P; const int maxn=100000+10; ll n,r;//n个点,r条边 ll dist[maxn]; ll dist2[maxn]; struct edge { ll to; ll cost; }; vector<edge> G[maxn]; ll cnt[maxn]; ///最短路条数 void dij_cnt(){ priority_queue<P,vector<P>,greater<P> > que; memset(dist,INF,sizeof(dist)); memset(cnt, 0, sizeof(cnt)); dist[0] = 0; que.push(P(0,0)); cnt[0] = 1; while(!que.empty()){ P p = que.top();que.pop(); ll v = p.second; if(dist[v]<p.first) continue; for(ll i = 0;i<G[v].size();++i){ edge &e = G[v][i]; if (dist[v]+e.cost < dist[e.to]){ dist[e.to] = dist[v]+e.cost; cnt[e.to] = cnt[v]; que.push(P(dist[e.to],e.to)); }else if (dist[v]+e.cost == dist[e.to]){ cnt[e.to] += cnt[v]; } } } } void solve(){ dij_cnt(); if (cnt[n-1] > 1){ cout << dist[n-1] << endl; return; } ///次短路模板 priority_queue<P,vector<P>,greater<P> > que; memset(dist,INF,sizeof(dist)); memset(dist2,INF,sizeof(dist2)); dist[0] = 0; que.push(P(0,0) ); while(!que.empty()){ P p = que.top(); que.pop(); ll v = p.second; ll d = p.first; if(dist2[v] < d) continue; for(ll i = 0;i<G[v].size();++i){ edge &e = G[v][i]; ll d2 = d+e.cost; if(dist[e.to] > d2){ swap(dist[e.to],d2); que.push(P(dist[e.to],e.to)); } if(dist2[e.to]>d2 && dist[e.to]<d2){ dist2[e.to] = d2; que.push(P(dist2[e.to],e.to)); } } } printf("%lld\n",dist2[n-1]); } int main() { int t; scanf("%d",&t); while(t--){ //初始化map for(ll i = 0;i<maxn;++i) G[i].clear(); scanf("%d%d",&n,&r); for(ll i=0;i<r;++i) { edge temp,temp1; ll u,v; ll w; scanf("%lld%lld%lld",&u,&v,&w); temp.to = v-1; temp.cost = w; temp1.to =u-1; temp1.cost=w; G[u-1].push_back(temp); G[v-1].push_back(temp1); } solve(); } return 0; }
相关文章推荐
- 2017 第十场多校训练 HDU 6181 Two Paths 次短路+Dijkstra
- HDU --- 6181 Two Paths 2017第十场多校签到题【裸次短路】
- 2017 Multi-University Training Contest 10 1011 Two Paths HDU 6181 (次短路+最短路数量)
- HDU 6181 Two Paths (次短路)
- hdu 6181 Two Paths(次短路径长度)POJ 3255 Roadblocks ( 次短路长度)
- 2017 Multi-University Training Contest 10 1011 Two Paths HDU 6181 (次短路)
- hdu 6181 Two Paths(次短路)
- [hdu 6181 Two Paths] Dijkstra求次短路
- Hdu 6181 Two Paths【次短路】
- HDU6181 Two Paths(次短路,路径记录,spfa,2017 HDU多校联赛 第10场)
- hdu 6181 Two Paths (次短路)
- hdu 6181 Two Paths (次短路)
- 2017多校第10场 HDU 6181 Two Paths 次短路
- HDU 6181 Two Paths(次短路变形)
- hdu 6181 Two Paths(最短路,spfa)
- HDU 6181 Two Paths【次短路】【模板题】
- HDU 6181 Two Paths 次短路
- HDU 6166 Senior Pan(多校第九场 二进制分组最短路)
- hdu 6181 (次短路
- HDU 6181 第k短路