题面

传送门

Sol

我们可以考虑每种\(rank\)的点\(u\)会被哪些点\(v\)感兴趣

如果\(dis[u][v]<\)所有满足\(rank\)大于\(rank[u]\)的点到\(v\)的距离

那么\(v\)一定对\(u\)感兴趣

我们可以先\(10\)遍最短路,处理出每种\(rank\)的点到所有点的最短路

计\(f[i][j]\)表示满足\(i\le rank\)的点到所有点的最短路

然后每次从一个点\(u\)出发,寻找对它感兴趣的点\(v\)

如果发现\(f[rank[u]+1][v]\le dis[u][v]\)

那么\(v\)不对\(u\)感兴趣,而且所有\(v\)能松弛到的点也都不会

那么可以\(SPFA\),每次不满足要求了就不丢进队列

复杂度是\(O(ans+10n)\)的,可以接受

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
const int _(3e4 + 5);
const int INF(1e9);
typedef long long ll; IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} int n, m, rk[_], first[_], cnt, f[15][_], vis[_], ans, dis[_], use[_];
struct Edge{
int to, next, w;
} edge[_ * 10];
struct Data{
int u, d; IL int operator <(RG Data A) const{
return d > A.d;
}
};
priority_queue <Data> Q;
queue <int> Deq; IL void Add(RG int u, RG int v, RG int w){
edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++;
} IL void Dijkstra(RG int p, RG int *dis){
for(RG int i = 1; i <= n; vis[i] = 0, ++i)
if(rk[i] == p) dis[i] = 0, Q.push((Data){i, 0});
else dis[i] = INF;
while(!Q.empty()){
RG Data x = Q.top(); Q.pop();
if(vis[x.u]) continue;
vis[x.u] = 1;
for(RG int e = first[x.u]; e != -1; e = edge[e].next){
RG int v = edge[e].to, w = edge[e].w;
if(x.d + w < dis[v]) Q.push((Data){v, dis[v] = x.d + w});
}
}
} IL int SPFA(RG int x){
RG int ret = 0;
for(RG int i = 1; i <= n; ++i) dis[i] = INF, use[i] = vis[i] = 0;
Deq.push(x), dis[x] = 0, vis[x] = 1;
while(!Deq.empty()){
RG int u = Deq.front(); Deq.pop();
if(!use[u]) use[u] = 1, ++ret;
for(RG int e = first[u]; e != -1; e = edge[e].next){
RG int v = edge[e].to, w = edge[e].w;
if(dis[u] + w < dis[v]){
dis[v] = dis[u] + w;
if(!vis[v] && f[rk[x] + 1][v] > dis[v]) vis[v] = 1, Deq.push(v);
}
}
vis[u] = 0;
}
return ret;
} int main(RG int argc, RG char* argv[]){
n = Input(), m = Input();
for(RG int i = 1; i <= n; ++i) rk[i] = Input(), first[i] = -1, f[11][i] = INF;
for(RG int i = 1; i <= m; ++i){
RG int u = Input(), v = Input(), w = Input();
Add(u, v, w), Add(v, u, w);
}
for(RG int i = 10; i; --i){
Dijkstra(i, f[i]);
for(RG int j = 1; j <= n; ++j) f[i][j] = min(f[i][j], f[i + 1][j]);
}
for(RG int i = 1; i <= n; ++i) ans += SPFA(i);
printf("%d\n", ans);
return 0;
}

最新文章

  1. 【原创】刚刚发现的SVN的几个有用的功能
  2. WIN7无法记住远程登录密码
  3. 浅谈压缩感知(二十八):压缩感知重构算法之广义正交匹配追踪(gOMP)
  4. 在Ubuntu 14 上安装 Nginx-RTMP 流媒体服务器
  5. linux软中断与硬中断实现原理概述
  6. C# Dictionary用法总结
  7. AVQueuePlayer,备用
  8. jquery中链式操作的this指向
  9. AppStore安装APP发生错误解决方法
  10. 水晶易表 Xcelsius 2008 安装指南 完美支持office2010(亲手体验)
  11. C#读取excel等表格常用方法
  12. Java实现猜字母游戏
  13. Linux下安全证书申请以及配置到Nginx
  14. 【Java编程】Java在dos窗口编译与执行的批处理
  15. maven的项目目录解析
  16. Selenium+PhantomJS替代方案
  17. js中把ajax获取的数据转化成树状结构(并做成多级联动效果)
  18. Spring cloud的Maven插件(一):repackage目标
  19. androidstudio全局搜索快捷键Ctrl+Shift+F失效的解决办法
  20. String 字符串中含有 Unicode 编码时,转为UTF-8

热门文章

  1. nginx高性能WEB服务器系列之二命令管理
  2. thinkphp3.2.3----图片上传并生成缩率图
  3. win7 设置docker加速器
  4. EndNote同步功能&lt;Sync&gt;
  5. [转] 打造基于CentOS7的xfce最简工作环境[转自smstong,在此记录一下]
  6. 当Appium中遇到alert(python篇)
  7. 二级C语言真题笔记
  8. react&amp;webpack使用css、less &amp;&amp; 安装原则 --- 从根本上解决问题。
  9. 利用C#结合net use命令破解域帐号密码
  10. android 仿网易新闻首页框架