比赛 |
2019级快乐小组模拟赛19.9.19 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
货车运输 |
最终得分 |
100 |
用户昵称 |
瑆の時間~無盡輪迴·林蔭 |
运行时间 |
0.687 s |
代码语言 |
C++ |
内存使用 |
16.57 MiB |
提交时间 |
2019-09-18 21:20:10 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
struct node1
{
int x,y,z;
};
node1 a[50001];
struct node2
{
int to,next,w;
};
node2 e[20001];
bool vis[10001];
int n,m,q,ans=999999999,val[10001],head[10001],cnt,f[10001][21],g[10001][21],h[100001],fa[10001];
bool cmp(node1 a1, node1 b)
{
return a1.z > b.z;
}
void dfs(int u, int depth)
{
vis[u] = true;
h[u] = depth;
for (int i = head[u]; i; i = e[i].next)
if (!vis[e[i].to])
{
f[e[i].to][0] = u;
g[e[i].to][0] = e[i].w;
dfs(e[i].to, depth + 1);
}
return;
}
int find(int x)
{
if(x==fa[x])
return x;
return fa[x]=find(fa[x]);
}
void add(int p, int q, int v)
{
e[++cnt].to = q;
e[cnt].next = head[p];
head[p] = cnt;
e[cnt].w = v;
}
void kruskal()
{
sort(a+1,a+1+m,cmp);
for(int i=1;i<=n;i++)
{
fa[i]=i;
}
for(int i=1;i<=m;i++)
{
int x=find(a[i].x);
int y=find(a[i].y);
if(x==y)
{
continue;
}
fa[x]=y;
add(a[i].x,a[i].y,a[i].z);
add(a[i].y,a[i].x,a[i].z);
}
}
int LCA(int a1,int b1)
{
ans=1000000000;
if(a1==b1)
{
return 0;
}
if(h[a1]<h[b1])
{
swap(a1,b1);
}
int k = int(log2(h[a1]));
for (int i = k; i >= 0; i--)
if (h[a1] - (1 << i) >= h[b1])
{
ans = min(ans, g[a1][i]);
a1 = f[a1][i];
}
if(a1==b1)
{
return ans;
}
//int k = int(log2(h[a1]));
for(int i=k;i>=0;i--)
{
if (f[a1][i] && f[a1][i] != f[b1][i])
{
ans = min(ans, min(g[a1][i], g[b1][i]));
a1 = f[a1][i];
b1 = f[b1][i];
}
}
ans = min(ans, min(g[a1][0], g[b1][0]));
return ans;
}
int main()
{
freopen ("truck.in","r",stdin);
freopen ("truck.out","w",stdout);
memset(vis, false, sizeof(vis));
memset(head, 0, sizeof(head));
memset(f, 0, sizeof(f));
memset(g, 127, sizeof(g)); //INF
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
kruskal();
scanf("%d", &q);
for (int i = 1; i <= n; i++)
if (!vis[i])
dfs(i, 1);
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i <= n; i++)
if (f[i][j - 1])
{
f[i][j] = f[f[i][j - 1]][j - 1];
g[i][j] = min(g[i][j - 1], g[f[i][j - 1]][j - 1]);
}
for (int i = 1; i <= q; i++)
{
int x, y;
scanf("%d%d", &x, &y);
if (find(x) != find(y))
printf("-1\n");
else
printf("%d\n", LCA(x, y));
}
return 0;
}