拼尽全力 55′,给后人留个拍子吧(a.cpp
放你的程序,b.cpp
放题解,无需 freopen
,调整 n_max
等调整数据范围):
#include <bits/stdc++.h>
using namespace std;
int random(int l, int r) {
return rand() % (r - l + 1) + l;
}
int n_max = 50000, m_max = 1000000, w_max = 100;
void data() {
ofstream fout("a.in");
int n = random(1, n_max), m = random(n - 1, m_max), s = random(1, n);
fout << n << " " << m << " " << s << "\n";
int cnt = 1;
for (int i = 1; i <= m; i++) {
if ((rand() % 2 or cnt + m - i + 1 == n) and cnt != n) {
cnt++;
fout << 2 << " " << random(1, cnt - 1) << " " << cnt << " " << random(1, n) << "\n";
} else
fout << 1 << " " << random(1, n) << " " << random(1, n) << " " << random(1, n) << " " << random(1, n) << " " << random(1, w_max) << "\n";
}
}
int main() {
srand(time(0));
int t = 0;
while (1) {
data();
system("a < a.in > a.out");
system("b < a.in > b.out");
if (system("fc a.out b.out"))
break;
cout << "#" << t << ", Accepted. \n";
t++;
}
return 0;
}
My Code:
#include <bits/stdc++.h>
#define pii pair<int, int>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
const int N = 5e4 + 10, M = 3e6 + 10;
int n, m, s;
struct OPT {
int opt, u, v, uu, vv, w;
} a[M];
vector<pii> g[M];
vector<int> gt[N];
void addg(int u, int v, int w) {
g[u].push_back({v, w});
}
void addgt(int u, int v) {
gt[u].push_back(v);
}
struct UDS {
int f[N];
UDS() {
for (int i = 0; i < N; i++)
f[i] = i;
}
int gf(int x) {
return f[x] == x ? x : f[x] = gf(f[x]);
}
void un(int x, int y) {
int fx = gf(x), fy = gf(y);
if (fx != fy)
f[fx] = fy;
}
} uds1, uds2;
int dep[N], f[N][16], in[N][16], out[N][16], idx;
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1;
f[u][0] = fa;
in[u][0] = ++idx, out[u][0] = ++idx;
addg(in[u][0], u, 0), addg(u, out[u][0], 0);
addg(in[u][0], fa, 0), addg(fa, out[u][0], 0);
for (int i = 1; i <= 15; i++) {
f[u][i] = f[f[u][i - 1]][i - 1];
in[u][i] = ++idx, out[u][i] = ++idx;
addg(in[u][i], in[u][i - 1], 0);
addg(in[u][i], in[f[u][i - 1]][i - 1], 0);
addg(out[u][i - 1], out[u][i], 0);
addg(out[f[u][i - 1]][i - 1], out[u][i], 0);
}
for (int v : gt[u]) {
if (v == fa)
continue;
dfs(v, u);
}
}
void upd(int x, int y, int u, int w, bool flag) {
if (x == y) {
if (flag)
addg(u, x, 0);
else
addg(x, u, w);
return;
}
if (dep[x] < dep[y])
swap(x, y);
for (int i = 15; i >= 0; i--)
if (dep[f[x][i]] >= dep[y]) {
if (flag)
addg(u, in[x][i], 0);
else
addg(out[x][i], u, w);
x = f[x][i];
}
if (x == y)
return;
for (int i = 15; i >= 0; i--)
if (f[x][i] != f[y][i]) {
if (flag)
addg(u, in[x][i], 0), addg(u, in[y][i], 0);
else
addg(out[x][i], u, w), addg(out[y][i], u, w);
x = f[x][i], y = f[y][i];
}
if (flag)
addg(u, in[x][0], 0), addg(u, in[y][0], 0);
else
addg(out[x][0], u, w), addg(out[y][0], u, w);
return;
}
void update(int u, int v, int uu, int vv, int w) {
if (uds2.gf(u) != uds2.gf(v) or uds2.gf(uu) != uds2.gf(vv))
return;
idx++;
upd(u, v, idx, w, 0);
upd(uu, vv, idx, w, 1);
}
namespace Dijkstra {
int dis[M];
bool vis[M];
void dijkstra(int s) {
memset(dis, 0x3f, sizeof dis);
dis[s] = 0;
priority_queue<pii, vector<pii>, greater<pii>> q;
q.push({0, s});
while (!q.empty()) {
auto [dist, u] = q.top();
q.pop();
if (vis[u])
continue;
vis[u] = true;
for (auto [v, w] : g[u]) {
if (dis[v] > dist + w) {
dis[v] = dist + w;
q.push({dis[v], v});
}
}
}
}
}
using namespace Dijkstra;
signed main() {
IOS;
cin >> n >> m >> s;
idx = n;
for (int i = 1; i <= m; i++) {
cin >> a[i].opt;
if (a[i].opt == 1) {
cin >> a[i].u >> a[i].v >> a[i].uu >> a[i].vv >> a[i].w;
} else {
cin >> a[i].u >> a[i].v >> a[i].w;
if (uds1.gf(a[i].u) == uds1.gf(a[i].v))
continue;
uds1.un(a[i].u, a[i].v);
addg(a[i].u, a[i].v, a[i].w);
addg(a[i].v, a[i].u, a[i].w);
addgt(a[i].u, a[i].v);
addgt(a[i].v, a[i].u);
}
}
dfs(1, 0);
for (int i = 1; i <= m; i++) {
if (a[i].opt == 1)
update(a[i].u, a[i].v, a[i].uu, a[i].vv, a[i].w);
else
uds2.un(a[i].u, a[i].v);
}
dijkstra(s);
for (int i = 1; i <= n; i++)
cout << (dis[i] >= 1e9 ? -1 : dis[i]) << " ";
return 0;
}