Two Paths HDU 次短路問題

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.
InputThe 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.
OutputFor each test case print length of valid shortest path in one line.Sample Input
2
3 3
1 2 1
2 3 4
1 3 3
2 1
1 2 1
Sample Output
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

此題就是求無向圖的次短路。即除去最短路以外的最短路,只要走的不一樣,可以和最短路一樣長。如果只有一條路,那麼有一段就得走兩遍(就像第二個樣例);
可以說是個板子題,直接套版子;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct mmp {                            
	int to,cost;                
   	mmp(int a,int b) {
		to=a;
		cost=b;
	}
};
ll d1[100001],d2[100001];               //d1爲從1到i的最短路,d2爲次短路
int m,n;
typedef pair<ll,int> p;                 //用pair對應長度和節點
vector<mmp> mmap[100001];               //用來儲存每條路,用動態數組和結構體,節省時間和空間
void solve() {
	priority_queue<p,vector<p>,greater<p> > q;          //用優先隊列
	q.push({0,1});                                     
	while(!q.empty()) {
		p now=q.top();
		q.pop();
		int too=now.second;
		ll  d=now.first; 
		if(d>d2[too])                            //若比次短路還長,跳過
			continue;
		for(int i=0; i<mmap[too].size(); i++) {
			ll dd=d+mmap[too][i].cost;
			int to=mmap[too][i].to;
			if(d1[to]>dd) {                 //若此條路比最短路短,交換並壓入隊列
				swap(dd,d1[to]);
				q.push({d1[to],to});
			}
			if(d2[to]>dd&&dd>d1[to]){      //若此條路比次短路短且比最短路長,與次短路交換位置並壓入隊列
				swap(dd,d2[to]);
				q.push({d2[to],to});
			}
		}
	}
	cout<<d2[n]<<endl;
}
int main() {
	int t;
	cin>>t;
	while(t--) {
		cin>>n>>m;
		for(int i=1; i<=n; i++) {            //將每條路都設置爲無窮大,並清空mmap
			d1[i]=d2[i]=1e18;
			mmap[i].clear();
		}
		for(int i=1; i<=m; i++) {
			int x,y,c;
			cin>>x>>y>>c;
			mmap[x].push_back(mmp(y,c));
			mmap[y].push_back(mmp(x,c));
		}
		solve();
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章