Codeforces 575F (最短路)

题意:n个点m条边的图,求两两无序点对中最短路第k小的长度。n,m<=2e5,k<=400。注意,自环不算最短路,(a,b), (b,a)只算一条。

尝试使用最麻烦的方法过题,写了一个map魔改的dijk卡内存卡过去。。。其实是个大水题,因为有用的边最多有400条,所以把最短的400条拿出来做个Floyd就好了。。。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define inc(i,n) for(int i=0;i<n;i++)
  4. typedef long long ll;
  5.  
  6. struct Edge{
  7. 	int v; ll w;
  8. 	bool operator<(const Edge &t) const{
  9. 		return w==t.w?v<t.v:w<t.w;
  10. 	}
  11. };
  12. vector<Edge> ed[200010];
  13. map<pair<int,int>,ll> dis;
  14. set<pair<int,int>> vis;
  15. struct Node{
  16. 	ll w;int fr, to;
  17. 	bool operator<(const Node &v)const{
  18. 		if (w==v.w) return fr==v.fr?to<v.to:fr<v.fr;
  19. 		return w>v.w;
  20. 	}
  21. };
  22.  
  23. int main(){
  24. 	int n,m,k; cin>>n>>m>>k;
  25. 	inc(i,m){
  26. 		int u,v; ll w; scanf("%d%d%lld",&u,&v,&w);
  27. 		ed[u].push_back({v,w});
  28. 		ed[v].push_back({u,w});
  29. 	}
  30. 	priority_queue<Node> qu;
  31. 	for (int i=1;i<=n;i++) qu.push({0,i,i}),sort(ed[i].begin(),ed[i].end());
  32. 	k*=2;
  33. 	while (1){
  34. 		Node t=qu.top(); qu.pop();
  35. 		if (vis.count({t.fr,t.to})) continue;
  36. 		if (t.fr^t.to) k--;
  37. 		if (k==0){
  38. 			cout<<t.w<<'\n';
  39. 			exit(0);
  40. 		}
  41. 		vis.insert({t.fr,t.to});
  42. 		int u=t.to;
  43. 		ll w0=t.w;
  44. 		int cnt=0;
  45. 		for (auto &e:ed[u]){
  46. 			int v=e.v;
  47. 			if (!vis.count({t.fr,v}) && (!dis.count({t.fr,v}) || dis[{t.fr,v}]>w0+e.w)){
  48. 				dis[{t.fr,v}]=w0+e.w;
  49. 				qu.push({w0+e.w,t.fr,v});
  50. 			}
  51. 			cnt++; if(cnt==500) break;
  52. 		}
  53. 	}
  54. 	return 0;
  55. }

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注