4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)
Posted wujiechao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)相关的知识,希望对你有一定的参考价值。
4144: [AMPPZ2014]Petrol
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 752 Solved: 298
[Submit][Status][Discuss]
Description
给定一个n个点、m条边的带权无向图,其中有s个点是加油站。
每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油站可以补满。
q次询问,每次给出x,y,b,表示出发点是x,终点是y,油量上限为b,且保证x点和y点都是加油站,请回答能否从x走到y。
Input
第一行包含三个正整数n,s,m(2<=s<=n<=200000,1<=m<=200000),表示点数、加油站数和边数。
第二行包含s个互不相同的正整数c[1],c[2],...c[s](1<=c[i]<=n),表示每个加油站。
接下来m行,每行三个正整数u[i],v[i],d[i](1<=u[i],v[i]<=n,u[i]!=v[i],1<=d[i]<=10000),表示u[i]和v[i]之间有一条长度为d[i]的双向边。
接下来一行包含一个正整数q(1<=q<=200000),表示询问数。
接下来q行,每行包含三个正整数x[i],y[i],b[i](1<=x[i],y[i]<=n,x[i]!=y[i],1<=b[i]<=2*10^9),表示一个询问。
Output
输出q行。第i行输出第i个询问的答案,如果可行,则输出TAK,否则输出NIE。
Sample Input
6 4 5
1 5 2 6
1 3 1
2 3 2
3 4 3
4 5 5
6 4 5
4
1 2 4
2 6 9
1 5 9
6 5 8
1 5 2 6
1 3 1
2 3 2
3 4 3
4 5 5
6 4 5
4
1 2 4
2 6 9
1 5 9
6 5 8
Sample Output
TAK
TAK
TAK
NIE
TAK
TAK
NIE
HINT
Source
朴素是先写个多源最短路把加油站的最小生成树所有可能边弄出来,然后后面按部就班地建个最小生成树,然后对树上写个主席树(st倍增)找u到v上最大值,和b比较一下。
那我们在把所有可能边弄出来以后停一下2333,我们连边不要对这条边俩端点连,而是对他们所在块的堆头节点连,这个建出来在查询最大值上是等效的。然后我们启发式地合并堆,这样可以把堆高度控制在logn,就不用再写个主席树啥的那麻烦了。直接两个端点往上一个一个跳,logn的不会有事的。
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define INF 0x3f3f3f3f 5 #define LL long long 6 #define pb push_back 7 #define mod 1000000007 8 #define ls(i) (i<<1) 9 #define rs(i) (i<<1|1) 10 #define mp make_pair 11 #define fi first 12 #define se second 13 using namespace std; 14 typedef pair<LL,int > pli; 15 const int N = 2e5+10; 16 bool need[N]; 17 vector<pli> e[N]; 18 struct node 19 { 20 int u,v; 21 LL w; 22 node(int _u=0,int _v=0,LL _w=0):u(_u),v(_v),w(_w) {} 23 }; 24 vector<node> ve; 25 int n,s,m,T; 26 priority_queue<pli,vector<pli>,greater<pli> > que; 27 int fuel[N]; 28 int fa[N],rfa[N],rk[N],dep[N]; 29 LL dis[N],val[N]; 30 bool vis[N]; 31 int pre[N]; 32 void dij() 33 { 34 while(!que.empty()) 35 { 36 pli now=que.top(); 37 que.pop(); 38 LL dist=now.fi; 39 int u=now.se; 40 if(vis[u]) continue; 41 vis[u]=1; 42 int sz=e[u].size(); 43 for(int i=0;i<sz;i++) 44 { 45 pli p=e[u][i]; 46 int w=p.fi; 47 int v=p.se; 48 if(!pre[v] || dis[v]>dis[u]+w) 49 { 50 dis[v]=dis[u]+w; 51 pre[v]=pre[u]; 52 que.push(mp(dis[v],v)); 53 } 54 else if(pre[u] != pre[v]) 55 ve.pb(node(pre[u],pre[v],dis[u]+dis[v]+w)); 56 } 57 } 58 return ; 59 } 60 bool cmp(node a,node b) 61 { 62 return a.w<b.w; 63 } 64 int Find(int u) 65 { 66 if(fa[u]!=u) 67 fa[u]=Find(fa[u]); 68 return fa[u]; 69 } 70 void Union() 71 { 72 sort(ve.begin(),ve.end(),cmp); 73 for(int i=1;i<=s;i++) 74 { 75 fa[fuel[i]]=fuel[i]; 76 rk[fuel[i]]=1; 77 } 78 int sz=ve.size(); 79 for(int i=0;i<sz;i++) 80 { 81 node p=ve[i]; 82 int u = p.u, v = p.v; 83 LL w = p.w; 84 u = Find(u), v = Find(v); 85 if(u==v) continue; 86 if(rk[u]<rk[v]) swap(u,v); 87 if(rk[u]==rk[v]) rk[u]++; 88 rfa[v]=u,fa[v]=u,val[v]=w; 89 } 90 return ; 91 } 92 void dealdep(int u) 93 { 94 if(dep[u]>0) return ; 95 if(fa[u]==u) 96 { 97 dep[u]=1; 98 return ; 99 } 100 dealdep(rfa[u]); 101 dep[u]=dep[rfa[u]]+1; 102 return ; 103 } 104 bool solve(int u,int v,LL b) 105 { 106 if(Find(u)!=Find(v)) return 0; 107 if(dep[u]<dep[v]) swap(u,v); 108 while(dep[u]>dep[v]) 109 { 110 if(b<val[u]) return 0; 111 u=rfa[u]; 112 } 113 if(u==v) return 1; 114 while(u!=v) 115 { 116 if(b<val[u]) return 0; 117 if(b<val[v]) return 0; 118 u=rfa[u]; 119 v=rfa[v]; 120 } 121 return 1; 122 } 123 int main() 124 { 125 scanf("%d%d%d",&n,&s,&m); 126 clr_1(dis); 127 for(int i=1;i<=s;i++) 128 { 129 scanf("%d",fuel+i); 130 que.push(mp(0,fuel[i])); 131 pre[fuel[i]]=fuel[i]; 132 dis[fuel[i]]=0; 133 } 134 for(int i=1;i<=m;i++) 135 { 136 int u,v; 137 LL w; 138 scanf("%d%d%lld",&u,&v,&w); 139 e[u].pb(mp(w,v)); 140 e[v].pb(mp(w,u)); 141 } 142 dij(); 143 Union(); 144 for(int i=1;i<=s;i++) 145 dealdep(fuel[i]); 146 int u,v; 147 LL b,maxn; 148 int q; 149 scanf("%d",&q); 150 while(q--) 151 { 152 scanf("%d%d%lld",&u,&v,&b); 153 if(solve(u,v,b)) 154 printf("TAK "); 155 else 156 printf("NIE "); 157 } 158 return 0; 159 }
以上是关于4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)的主要内容,如果未能解决你的问题,请参考以下文章
4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)