记录编号 |
160526 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOIP 2013]货车运输 |
最终得分 |
100 |
用户昵称 |
rpCardinal |
是否通过 |
通过 |
代码语言 |
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;
}