记录编号 160526 评测结果 AAAAAAAAAA
题目名称 [NOIP 2013]货车运输 最终得分 100
用户昵称 GravatarrpCardinal 是否通过 通过
代码语言 C++ 运行时间 0.130 s
提交时间 2015-04-28 09:03:38 内存使用 4.74 MiB
显示代码纯文本
#include <cstdio>
#include <climits>
#include <algorithm>
#define MM 17
using namespace std;

struct adlist
{
    int u[10010],v[20010],w[20010],p[20010],m;
    void insert(int x,int y,int z)
    {
        ++m; v[m]=y; w[m]=z; p[m]=u[x]; u[x]=m;
        ++m; v[m]=x; w[m]=z; p[m]=u[y]; u[y]=m;
    }
}g;

struct edge
{
    int x,y,z;
    bool operator<(edge B)const
    {return z>B.z;}
}E[100010];

struct djset
{
    int f[10010];
    void init(int n) {for (int i=1;i<=n;++i) f[i]=i;}
    int F(int x) {f[x]=f[x]==x?x:F(f[x]); return f[x];}
}S;

int p[MM][10010],h[10010],d[MM][10010];

void init(int x,int f,int dis)
{
    p[0][x]=f; d[0][x]=dis; h[x]=h[f]+1;
    for (int i=1;i<MM;++i) p[i][x]=p[i-1][p[i-1][x]];
    for (int i=1;i<MM;++i) d[i][x]=min(d[i-1][x],d[i-1][p[i-1][x]]);
    for (int i=g.u[x];i;i=g.p[i])
        if (g.v[i]!=f) init(g.v[i],x,g.w[i]);
}

int work(int x,int y)
{
    int ret=INT_MAX;
    if (h[x]<h[y]) swap(x,y); int dt=h[x]-h[y];
    for (int i=MM-1;i>=0;--i)
        if ((dt>>i)&1) {ret=min(ret,d[i][x]); x=p[i][x];}
    for (int i=MM-1;i>=0;--i)
        if (p[i][x]!=p[i][y])
        {
            ret=min(ret,d[i][x]); x=p[i][x];
            ret=min(ret,d[i][y]); y=p[i][y];
        }
    return x==y?ret:min(ret,min(d[0][x],d[0][y]));
}

int main()
{
    freopen("truck.in","r",stdin);
    freopen("truck.out","w",stdout);
    int n,m; scanf("%d%d",&n,&m);
    for (int i=1;i<=m;++i)
        scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].z);
    sort(E+1,E+m+1); S.init(n);
    for (int i=1;i<=m;++i)
    {
        int fx=S.F(E[i].x),fy=S.F(E[i].y);
        if (fx==fy) continue; S.f[fy]=fx;
        g.insert(E[i].x,E[i].y,E[i].z);
    }
    for (int i=1;i<=n;++i) if (!h[i]) init(i,0,0);

    int q; scanf("%d",&q);
    while (q--)
    {
        int x,y; scanf("%d%d",&x,&y);
        if (S.F(x)==S.F(y))
            printf("%d\n",work(x,y));
        else
            printf("-1\n");
    }
    fclose(stdin); fclose(stdout);
    return 0;
}