Dijstra,Kruskal,在线LCA,树上倍增,手写堆【╮(╯▽╰)╭被stl嘲讽了】。
#include<map>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define L(x) (x<<1)
#define R(x) ((x<<1)|1)
const int MAXM = 200005,MAXN = 100005,logN = 18;
const long long INF = 2e16;
int n, m;
struct Edge_list{int v , next;long long w;}edge[MAXM<<1] = {0};
int head[MAXN] = {0},el = 0;
struct Edge_star{int u , v ;long long w;}side[MAXM<<1] = {0};
int sl = 0;
int gfa[MAXN] = {0} , tfa[MAXN][logN] = {0};
int dep[MAXN] = {0};long long tmax[MAXN][logN] = {0};
char cli[MAXN] = {'\0'};
bool crl[MAXN] = {false};
int heap[MAXN] = {0},site[MAXN] = {0}, hl;long long dist[MAXN] = {0};
int from[MAXN] = {0};bool flag[MAXN] = {0};
bool starcmp(const Edge_star &a,const Edge_star &b){return (a.w<b.w);}
void newedge(int u,int v,long long w)
{
++el,edge[el].v = v, edge[el].w = w;
edge[el].next = head[u],head[u] = el;
}
int find_fa(int a)
{
if(a == gfa[a])return a;
else
{
gfa[a] = find_fa(gfa[a]);
return gfa[a];
}
}
void update(int x){site[heap[x]] = x;}
void flood(int a)
{
int min = a;
if(L(a) <= hl && dist[heap[L(a)]] < dist[heap[min]])min = L(a);
if(R(a) <= hl && dist[heap[R(a)]] < dist[heap[min]])min = R(a);
if(min != a)
{
std::swap(heap[min],heap[a]);
update(min); update(a);
flood(min);
}
}
void climb(int a)
{
if(a == 1)return;
int fa = a>>1;
if(dist[heap[a]] < dist[heap[fa]])
{
std::swap(heap[fa],heap[a]);
update(fa);update(a);
climb(fa);
}
}
void inheap(int x)
{
heap[++hl] = x;
update(hl);
flag[x] = true;
climb(hl);
}
int outheap()
{
int ret = heap[1];
heap[1] = heap[hl];
heap[hl--] = 0;
flag[ret] = false;
site[ret] = 0;
update(1);
flood(1);
return ret;
}
void Dijstra()
{
hl = 0;
for(int i = 1 ;i <= n ;i++)dist[i] = INF;
for(int i = 1 ;i <= n ;i++)
if(crl[i]==true)
{
dist[i] = 0;
from[i] = i;
heap(i);
}
for(int j = 1; j <= n ; j++)
{
int u = outheap();
for(int i = head[u]; i ; i = edge[i].next)
{
int v = edge[i].v;
long long tmp = dist[u] + edge[i].w;
if(tmp < dist[v])
{
dist[v] = tmp;
from[v] = from[u];
if(flag[v] == true)climb(site[v]);
else inheap(v);
}
}
}
}
void newgraph()
{
for(int i = 1 ; i <= n ; i++)
for(int j = head[i]; j ; j = edge[j].next)
{
int p = edge[j].v;
if(from[i] < from[p])
{
++sl;
side[sl].u = from[i], side[sl].v = from[p];
side[sl].w = dist[i] + dist[p] + edge[j].w;
}
}
for(int i = 1 ; i <= n ; i++)head[i] = 0;
el = 0;//clear edge
}
void Kruskal()
{
int cnt = 0;
for(int i = 1 ; i <= n ; i++)
if(crl[i] == true)gfa[i] = i, cnt++;
std::sort(side+1,side+sl+1,starcmp);
for(int i = 1 ; i <= sl ;i++)
{
int fu = find_fa(side[i].u);
int fv = find_fa(side[i].v);
if(fu != fv)
{
newedge(side[i].u,side[i].v,side[i].w);
newedge(side[i].v,side[i].u,side[i].w);
if(fu > fv)std::swap(fu,fv);
gfa[fv] = fu;
}
if((el>>1) == cnt - 1)return;
}
return;//failed
}
void buildtree(int a)
{
dep[a] = dep[tfa[a][0]]+1;
for(int i = head[a]; i; i = edge[i].next)
{
int p = edge[i].v;
if(p == tfa[a][0])continue;
tfa[p][0] = a;
tmax[p][0] = edge[i].w;
buildtree(p);
}
}
void getpre()
{
for(int j = 1 ; j < logN; j++)
for(int i = 1; i <= n; i++)
{
tfa[i][j] = tfa[tfa[i][j-1]][j-1];
tmax[i][j] = std::max(tmax[tfa[i][j-1]][j-1],tmax[i][j-1]);
}
}
long long getmax(int u,int v)
{
long long ret = 0;
if(dep[u]<dep[v])std::swap(u,v);//dep[u]>=dep[v]
for(int i = logN - 1; i >= 0;i--)
if(dep[tfa[u][i]] >= dep[v])
{ret = std::max(ret,tmax[u][i]); u = tfa[u][i];}
if(u == v)return ret;
for(int i = logN - 1; i >= 0; i--)
if(tfa[u][i]!=tfa[v][i])
{
ret = std::max(ret,tmax[u][i]);
ret = std::max(ret,tmax[v][i]);
u = tfa[u][i], v = tfa[v][i];
}
ret = std::max(ret,std::max(tmax[u][0],tmax[v][0]));
return ret;
}
char cc;
void scan(int &x)
{
x = 0;
do{cc = getchar();}while(!(cc >= '0' && cc <= '9'));
do{
x = (x<<3) + (x<<1) + cc - '0';
cc = getchar();
}while(cc >= '0' && cc <= '9');
}
char ss[15];short cl = 0;
void print(int x)
{
while(x){ss[++cl] = x%10 + '0';x/=10;}
while(cl){putchar(ss[cl--]);}puts("");
}
int main()
{
int st;
#ifndef ONLINE_JUDGE
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
#endif
scan(n);scan(m);
scanf("%s",cli+1);
for(int i = n ;i >= 1;i--)
{
if(cli[i]=='0')crl[i] = false;
else st = i,crl[i] = true;
}
for(int i = 1 ; i <= m ;i++)
{
int u,v,w; scan(u); scan(v); scan(w);
newedge(u,v,w); newedge(v,u,w);
}
Dijstra();
newgraph();
Kruskal();
tfa[st][0] = 0;
tmax[st][0] = 0;
buildtree(st);
getpre();
int q; scan(q);
while(q--)
{
int u,v; scan(u); scan(v);
print(getmax(u,v));
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}