A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路。每一条道路对车辆都有重量限制,简称限重。
现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
第一行有两个用一个空格隔开的整数 n,mn,m,表示 AA 国有 nn 座城市和 mm 条道路。
接下来 mm 行每行三个整数 x, y, zx,y,z,每两个整数之间用一个空格隔开,表示从 xx 号城市到 yy 号城市有一条限重为 zz 的道路。
注意: x \neq yx=y,两座城市之间可能有多条道路 。
接下来一行有一个整数 qq,表示有 qq 辆货车需要运货。
接下来 qq 行,每行两个整数 x,yx,y,之间用一个空格隔开,表示一辆货车需要从 xx 城市运输货物到 yy 城市,保证 x \neq yx=y
共有 qq 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。
如果货车不能到达目的地,输出 -1−1。
输入 #1复制
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出 #1复制
3
-1
3
对于 30\%30% 的数据,1 \le n < 10001≤n<1000,1 \le m < 10,0001≤m<10,000,1\le q< 10001≤q<1000;
对于 60\%60% 的数据,1 \le n < 10001≤n<1000,1 \le m < 5\times 10^41≤m<5×104,1 \le q< 10001≤q<1000;
对于 100\%100% 的数据,1 \le n < 10^41≤n<104,1 \le m < 5\times 10^41≤m<5×104,1 \le q< 3\times 10^41≤q<3×104,0 \le z \le 10^50≤z≤105。
这个题目我没有看板子ac的。
#include
using namespace std;
const int maxn = 10010;
const int inf = 0x3f3f3f3f;
struct node
{
int x, y, z;
} N[maxn * 5 + 10];
vector > V[maxn];
int f[maxn], anc[maxn][(int)log2(maxn)], dis[maxn][(int)log2(maxn)], Dep[maxn],vis[maxn];
void init(int n)
{
for (int i = 0; i <= n; i++)
f[i] = i;
memset(anc, 0, sizeof(anc));
memset(dis, inf, sizeof(dis));
memset(Dep, 0, sizeof(Dep));
memset(vis,0,sizeof(vis));
}
int Find(int x)
{
return f[x] == x ? x : (f[x] = Find(f[x]));
}
void Merge(int x, int y)
{
int X = Find(x);
int Y = Find(y);
f[X] = Y;
return;
}
void dfs(int x, int dep)
{
vis[x]=1;
for(auto it =V[x].begin(); it!=V[x].end(); it++)
{
if(vis[(*it).first])
continue;
anc[(*it).first][0] = x;
dis[(*it).first][0] = (*it).second;
Dep[(*it).first] = dep+1;
for (int i = 1; i <=(int)log2(dep+1); i++)
{
anc[(*it).first][i] = anc[anc[(*it).first][i-1]][i - 1];
dis[(*it).first][i] = min(dis[(*it).first][i - 1], dis[anc[(*it).first][i-1]][i - 1]);
}
dfs((*it).first, dep + 1);
}
return;
}
int solve(int x, int y)
{
if (Find(x) != Find(y))
return -1;
int ans = inf;
if (Dep[x] < Dep[y])
swap(x, y);
int C = Dep[x] - Dep[y];
for (int i = 0; i <=(int)log2(C); i++)
{
if (((1 << i) & C))
{
ans = min(ans, dis[x][i]);
x = anc[x][i];
}
}
if (x != y)
for (int i =(int)(log2(Dep[x])); i >= 0; i--)
{
if(i==0)
{
ans = min(min(ans, dis[x][i]), dis[y][i]);
x = anc[x][i];
y = anc[y][i];
}
else
{
if (anc[x][i]!=anc[y][i])
{
ans = min(min(ans, dis[x][i]), dis[y][i]);
x = anc[x][i];
y = anc[y][i];
}
}
}
if(x!=y)
ans= min(ans,min(dis[x][0],dis[y][0]));
return ans;
}
int main()
{
int n, m, q;
cin >> n >> m;
init(n);
for (int i = 0; i < m; i++)
{
cin >> N[i].x >> N[i].y >> N[i].z;
}
sort(N, N + m, [=](node a, node b)
{
return a.z > b.z ;
});
for (int i = 0; i < m; i++)
{
if (Find(N[i].x) != Find(N[i].y))
{
Merge(N[i].x, N[i].y);
V[N[i].x].push_back(make_pair(N[i].y, N[i].z));
V[N[i].y].push_back(make_pair(N[i].x, N[i].z));
}
}
for (int i = 1; i <= n; i++)
{
if (vis[i])
continue;
dfs(i, 0);
}
int x, y;
cin>>q;
while (q--)
{
cin >> x >> y;
cout << solve(x, y) << endl;
}
}
/*
5 6
1 2 1
2 3 2
3 6 3
1 4 1
4 5 2
5 7 3
100
3 5
6 7
*/