Connections between cities
【题目链接】Connections between cities
【题目类型】LCA Tarjan
&题意:
输入一个森林,总节点不超过N(N<10000),由C次询问(C<1000000),每次询问两个点,如果来联通输出,两点之间的距离,如果不来联通,输出“Not connected”
&题解:
md,就没人吐槽这题询问时有相等的情况吗?我被这个坑了一天= = 最后把ans数组置为-1才过的,以前一直初始化为0,就总是wa,因为有ans0的情况,就是在ij时.
【时间复杂度】(O(n+q))
&代码:
#include <cstdio>
#include <bitset>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
#define cle(a,v) memset(a,(v),sizeof(a))
const int maxn = 2e4 + 7, maxq = 2e6 + 7;
int n, m, q, Head[maxn], QHead[maxn], Dis[maxn], id, iq, fa[maxn], ans[maxq / 2], vis[maxn];
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
struct Edge {
int to, next, w;
} ed[maxn], Qed[maxq];
void ori() {
cle(Head, -1); cle(QHead, -1);
id = iq = 0;
cle(vis, 0);
cle(Dis, 0);
cle(ans, -1);
}
void Add(int u, int v, int w) {
ed[id].to = v; ed[id].w = w; ed[id].next = Head[u];
Head[u] = id++;
}
void QAdd(int u, int v, int index) {
Qed[iq].to = v, Qed[iq].next = QHead[u], Qed[iq].w = index;
QHead[u] = iq++;
}
void LCA(int r, int d, int top) {
fa[r] = r;
vis[r] = top;
Dis[r] = d;
for(int k = Head[r]; ~k; k = ed[k].next) {
if(!vis[ed[k].to]) {
LCA(ed[k].to, d + ed[k].w, top);
fa[ed[k].to] = r;
}
}
for(int k = QHead[r]; ~k; k = Qed[k].next) {
if(vis[Qed[k].to] == top) {
ans[Qed[k].w] = Dis[r] + Dis[Qed[k].to] - 2 * Dis[find(Qed[k].to)];
}
}
}
int main() {
freopen("E:1.in", "r", stdin);
while(~scanf("%d%d%d", &n, &m, &q)) {
ori();
int u, v, w;
fo(i, 1, m) {
scanf("%d%d%d", &u, &v, &w);
Add(u, v, w); Add(v, u, w);
}
fo(i, 1, q) {
scanf("%d%d", &u, &v);
QAdd(u, v, i); QAdd(v, u, i);
}
fo(i, 1, n) {
if(!vis[i]) {
LCA(i, 0, i);
}
}
fo(i, 1, q) {
if(ans[i] == -1) printf("Not connected
");
else printf("%d
", ans[i]);
}
}
return 0;
}