比赛 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;
}