bzoj4144 [AMPPZ2014]Petrol
图论 最短路 并查集

1、这道题我们主要就是要求出距离一个油站的最近的油站
首先我们dijkstra 求出任意一个点到 离他最近的油站的距离
2、然后会发现 如果一条边的两个端点 的最近油站不同的话
那么这条边就会在这两个油站的最短路上
3、然后对于每一条边 我们将他的权值 变为
dis[ u ] + dis[ v ] + e[ i ][ j ]
如果u与v最近油站相同 那么这个无意义
如果不同 那么久表示 u 最近油站 到 v 最近油站的最近距离
4、然后我们就 排下序
离线做 取出 满足 最多加油的边 并查集 维护一下连通性就行了

  1 #include <bits/stdc++.h>
  2 using namespace std ;
  3
  4 const int N = 200011,inf = 1e9 ;
  5 struct edge{
  6     int to,pre,val ;
  7 }e[N*2];
  8 struct ek{
  9     int x,y,dis ;
 10 }te[N];
 11 int vis[N],head[N],dis[N],c[N],ans[N],fa[N],rank[N] ;
 12 int n,m,Q,s,cnt,now ;
 13
 14 struct node{
 15     int val,pos ;
 16 }p ;
 17 struct cmp{
 18     bool operator() (node a,node b )
 19     {
 20         return a.val > b.val ;
 21     }
 22 };
 23 struct qu{
 24     int s,t,b,id ;
 25 }q[N] ;
 26
 27 inline int read()
 28 {
 29     int x = 0 , f = 1 ;
 30     char ch = getchar() ;
 31     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; }
 32     while(ch>='0'&&ch<='9') { x = x * 10+ch-48 ; ch = getchar() ; }
 33     return x * f ;
 34 }
 35
 36 inline void add(int x,int y,int v)
 37 {
 38     e[++cnt].to = y ;
 39     e[cnt].pre = head[x] ;
 40     e[cnt].val = v ;
 41     head[ x ] = cnt ;
 42 }
 43
 44 inline void dij()
 45 {
 46     priority_queue <node,vector<node>,cmp> Q ;
 47     for(int i=1;i<=n;i++) vis[ i ] = 0 ,dis[ i ] = inf ;
 48     int u,v ;
 49     for(int i=1;i<=s;i++)
 50     {
 51         p.val = 0 ; p.pos = c[ i ] ;
 52         Q.push(p) ; dis[ c[ i ] ] = 0 ;
 53      }
 54     while(!Q.empty())
 55     {
 56         u = Q.top().pos ;
 57         Q.pop() ;
 58         if( vis[ u ] ) continue ;
 59         vis[ u ] = 1 ;
 60         for(int i=head[u];i;i=e[i].pre)
 61         {
 62             v = e[ i ].to ;
 63             if( dis[ u ] + e[ i ].val < dis[ v ] )
 64             {
 65                 dis[ v ] = dis[ u ] + e[ i ].val ;
 66                 p.pos = v ; p.val = dis[ v ] ;
 67                 Q.push( p ) ;
 68             }
 69         }
 70     }
 71 }
 72
 73 inline bool cmp1(ek a,ek b) { return a.dis < b.dis ; }
 74 inline bool cmp2(qu a,qu b) { return a.b < b.b ; }
 75
 76 inline int find(int x)
 77 {
 78     if(x==fa[x]) return x ;
 79     return fa[ x ] = find(fa[x]) ;
 80 }
 81
 82 inline void Union(int x,int y)
 83 {
 84     x = find(x) ; y = find(y) ;
 85     if(x==y) return ;
 86     if(rank[ x ] > rank[ y ]) swap(x,y) ;
 87     fa[ x ] = y ;
 88     rank[y]+= rank[x]==rank[y] ;
 89 }
 90
 91 int main()
 92 {
 93     n = read() ; s = read() ; m = read() ;
 94     for(int i=1;i<=s;i++) c[ i ] = read() ;
 95     int x,y,v ;
 96     for(int i=1;i<=m;i++)
 97     {
 98         x = read() ; y = read() ; v = read() ;
 99         te[ i ] = (ek){ x,y,v } ;
100         add(x,y,v) ;
101         add(y,x,v) ;
102     }
103     dij() ;
104     for(int i=1;i<=m;i++)
105         te[ i ].dis = dis[ te[ i ].x ] + dis[ te[ i ].y ] + te[ i ].dis;
106     Q = read() ;
107     for(int i=1;i<=Q;i++)
108         q[ i ].s = read() ,q[ i ].t = read() ,q[ i ].b = read(),q[ i ].id = i ;
109
110     for(int i=1;i<=n;i++)
111         fa[ i ] = i ,rank[ i ] = 0 ;
112     sort( te+1,te+m+1,cmp1 ) ;
113     sort( q+1,q+Q+1,cmp2 ) ;
114     now = 1 ;
115     for(int i=1;i<=Q;i++)
116     {
117         while(now<=m&&te[ now ].dis <= q[ i ].b)
118         {
119             Union( te[ now ].x,te[ now ].y ) ;
120             now++ ;
121         }
122         ans[ q[ i ].id ] = find( q[ i ].s ) == find(q[ i ].t) ;
123     }
124     for(int i=1;i<=Q;i++)
125         puts(ans[ i ] ? "TAK" : "NIE" ) ;
126      return 0 ;
127 }

转载于:https://www.cnblogs.com/third2333/p/7149250.html

bzoj4144 [AMPPZ2014]Petrol 图论 最短路 并查集相关推荐

  1. HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集

    题目链接 题意:就是给你一堆关系,看能不能排出个确定的顺序 做法: 1. 拓扑排序+并查集 应该很容易想到的一种思路,大于小于建立单向边.对于相等的呢,就把他们缩成一个点.就用并查集缩成一个点就行了 ...

  2. 图论500题 ---- 并查集求路径上最大值最小不超过K的点对数 HDU Portal

    题目链接 题目大意: 就给你一个图,qqq次询问,问你这个图上有多少对点之间的所以路径上的最大值的最小值不超过kkk? 解题思路: 首先我们知道这本质上就是求两个点联通的路径上的最大值最小是多少? 那 ...

  3. 【图论】【并查集】矩形(ssl 1222)

    矩形 ssl 1222 题目大意: 有n个矩阵,现在将有重叠部分的两个矩阵合并成一个图形,问有多少个图形 原题: 题目描述 在一个平面上有n个矩形.每个矩形的边都平行于坐标轴并且都具有值为整数的顶点. ...

  4. 数据结构与算法A实验六图论---7-9 最短路径(并查集Dijkstra)

    给定一个有N个顶点和E条边的无向图,顶点从0到N−1编号.请判断给定的两个顶点之间是否有路径存在.如果存在,给出最短路径长度. 这里定义顶点到自身的最短路径长度为0. 进行搜索时,假设我们总是从编号最 ...

  5. 图论 ---- 启发式合并 + 并查集模拟 + 证明 F. Phoenix and Earthquake

    题目大意: 给你nnn个点,mmm条边,限制xxx,每个点都有沥青aia_iai​ ,定义合并两个点即两点之间有边且au+av≥xa_u+a_v\ge xau​+av​≥x,合并之后的沥青为au+av ...

  6. 图论500题 ---- 并查集+树形dp+枚举 求解动态的最小生成树 HDU 4126

    题目链接 题目大意: 给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边(可以经过可疑边新的花费构建的边),注意每次只出现一条 ...

  7. 图论8 并查集深入解析——边带权并查集和拓展域并查集和最小生成树

    我们先复习一下并查集的基本知识. 并查集的三个操作:查询,初始化,合并:并查集的结构:操作方法以及代码:路径压缩优化(详见<图论7 弗洛伊德&并查集算法详解>). 补充一下,并查集 ...

  8. 图论(最短路,最小生成树,并查集)

    本文目录: tarjan算法(判断环) 最小生成树(Kruskal算法) 最小生成树(Prim算法) 优先队列实现dijkstra(最短路) 并查集(求环) floyd(弗洛伊德) (最短路) 判断环 ...

  9. 图论最短路及生成树(Prim,Djikstra,Spfa,Bellan-ford,kruskal,topsort)

    图论在算法中具有举足轻重的地位,只有学好图才能游刃有余.本文章将介绍图论中一些基础算法,可以说总结的十分全面,文章结尾也会分析各算法的差异,清晰易懂.并附上代码模板. 图论(最短路.生成树) 一.拓扑 ...

最新文章

  1. 阿里云数据库专家白宸:Redis带你尽享丝滑!(图灵访谈)
  2. java命令行选项6_6.jdk命令行工具
  3. RabbitMQ封装实战
  4. php数组函数(分类基本数组函数,栈函数,队列)
  5. sphinx和coreseek
  6. ffplay分析 (视频从Frame(解码后)队列取数据到SDL输出)
  7. C++面试题-指针-指针常量与常量指针
  8. 2023年计算机网络考研真题详解
  9. 自媒体平台数据统计分析爬虫之【一点号】模拟登陆分析详解及数据统计接口详解
  10. 爱思唯尔(ELSEVIER)期刊LaTeX通用模板下载及使用技巧
  11. Qt Creator启动慢的解决方法
  12. iOS 11 正式发布!最全功能介绍 + 视频 ...
  13. C++ 静态函数与虚函数的区别
  14. Android音频学习之MediaExtractor,提取音频视频轨道数据(从视频中分离音频视频数据)
  15. 京峰教育Linux笔记
  16. 51单片机auxr寄存器_AT89S51存储器的结构
  17. Flink cdc +doris生产遇到的问题汇总-持续更新
  18. 搭建简易的物联网服务端和客户端-Maibu控制(二十一)
  19. 怎么一键完美抠图?无需PS!快来看看!
  20. 华侨大学计算机学院保研情况,关于华大保研。

热门文章

  1. 查询去重_【Freya的MySQL课堂】DQL基础查询
  2. CSS2--字体样式
  3. 四五月份:关键词是沟通、绘画和SQL
  4. 【转】DB2 常用命令
  5. WP7应用开发笔记(3) 界面设计
  6. Oracle 随机获取N条数据
  7. window.onload和$(document).ready(function(){})的区别
  8. 在bootstrap table中使用Tooltip
  9. java运算符 —(5)
  10. springmvc框架下Filter过滤器中过滤文件后 后续 controller为空的问题