题意:给定一个带权有向图,有q组询问,每次询问在有向图的所有路径中,第k小的路径权值

解题思路:因为k最大只有5e4,考虑暴力搜索出前maxk小的路径并用数组记录权值,然后就可以O(1)查询。

具体实现:暴力搜索时可以借助Dijkstra最短路的思想,即用已知的最短路更新得出新的最短路。先将所有的边都装进一个multiset里面,然后每次将multiset里的首元素取出,作为新的答案,然后再用它来更新新的最短路,这样不断扩散的话就可以得到答案。

但是,这样可能会TLE或MLE,考虑再加加优化,首先我们只需要前maxk小的路径,所以multiset的可以限制在maxk以内,这样就不会MLE了,然后我们还可以先对每个节点的邻接表中的边按权值从小到大排序,这样在枚举的时候如果新路径的权值大于multiset中的最大值就可以直接break掉,这样就不会TLE了。

AC代码:

#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int maxn=5e4+5;
const int MAXK=5e4+5;
int n,m,q,k; struct Edge{
int id,u,v;
ll w;
bool operator<(const Edge& b)const{return w<b.w;}
}; multiset<Edge>s; vector<Edge>G[maxn];
ll ans[MAXK];
int tot,maxk,qry[maxn]; void init(){
for(int i=1;i<=n;i++)sort(G[i].begin(),G[i].end());
int cnt=0;
while(true){ //cout<<"S:\n";for(auto i:s)cout<<i.u<<" "<<i.v<<" "<<i.w<<"\n"; ans[++cnt]=s.begin()->w;
Edge e=*s.begin(),tmp;
s.erase(s.begin());
if(cnt>=maxk)break; int psz=(int)s.size(); int sz=(int)G[e.v].size(); if((int)s.size()+sz<=maxk){
for(int i=0;i<sz;i++){
Edge t=G[e.v][i];
tmp.id=++tot;tmp.u=e.u;tmp.v=t.v;tmp.w=e.w+t.w;
s.insert(tmp);
}
}
else{
for(int i=0;i<sz;i++){
Edge t=G[e.v][i];
if((int)s.size()<=maxk){
tmp.id=++tot;tmp.u=e.u;tmp.v=t.v;tmp.w=e.w+t.w;
s.insert(tmp);
}
else{
Edge last=*(--s.end());
if(last.w>e.w+t.w){
s.erase(last);
tmp.id=++tot;tmp.u=e.u;tmp.v=t.v;tmp.w=e.w+t.w;
s.insert(tmp);
}
else break;
}
}
}
}
} int main()
{
//#ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
//#endif
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&n,&m,&q); for(int i=1;i<=n;i++)G[i].clear();
s.clear();tot=0; int u,v;
ll w;
Edge tmp;
for(int i=1;i<=m;i++){
scanf("%d %d %lld",&u,&v,&w);
tmp.id=++tot;tmp.u=u;tmp.v=v;tmp.w=w;
G[u].push_back(tmp);
s.insert(tmp);
}
maxk=0;
for(int i=1;i<=m;i++){
scanf("%d",&qry[i]);
maxk=max(maxk,qry[i]);
}
init();
for(int i=1;i<=m;i++){
printf("%lld\n",ans[qry[i]]);
}
}
return 0;
}

最新文章

  1. Windows 上如何安装Sqlite
  2. Hibernate5.2之一对一外键关联(五)
  3. 使用C++扩展Python的功能 转自:http://blog.csdn.net/magictong/article/details/8897568#comments
  4. Sublime Text3注册码(可用)
  5. 将字符转换为unicode码
  6. 常用Raspberry Pi周边传感器的使用教程
  7. Android开发之异步消息处理机制AsyncTask
  8. http协言和web本质
  9. Python - 判断list是否为空
  10. Maven classifier 元素妙用
  11. 2015年蓝桥杯省赛A组c++第8题(迭代法)
  12. linux+vs2013编译静态库和动态库
  13. Everything:速度最快的文件名搜索工具(Linux版本) 转
  14. OpenVPN Windows 平台安装部署教程
  15. FineUI Grid中WindowField根据列数据决定是否Enalble
  16. php数据结构之二叉树
  17. HDU 4123 Bob’s Race(RMQ)
  18. 【带修改的主席树】BZOJ1901-Dynamic Rankings
  19. Java SHA256/Base64转.NET(C#)实现---(华为云云市场.NET版本加密方式)
  20. tomcat报503 或者无法启动应用

热门文章

  1. kubernetes监控prometheus配置项解读
  2. aria2使用ajax调用/页面浏览器RPC调用aria2
  3. css实现折扇效果
  4. printf函数和putchar函数
  5. 题解 UVA10457
  6. Linux学习笔记 一 第三章 Linux常用命令
  7. Vue CLI3 移动端适配 【px2rem 或 postcss-plugin-px2rem】
  8. Python 用DataFrame读 存 excel
  9. Python 使用BrowserMob Proxy + selenium 获取Ajax加密数据
  10. 使用IDEA连接mysql后不显示表的解决方案