我根据 1 <= dist[i] <= 2 差分约束建图跑最长路。再约束 dist[1] = 0。此外,观察到原图最长路,在处理后的图上边权也应该都是 1,因此再加上限制 dist[v] = 1 (这里 v 是从 1 到 n 最长路上的点)。然而wa on test 5,期望输出No 但是我输出 Yes。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, M = 1e5 + 10;
int e[M], nxt[M], idx = 1, h[N], hs[N], w[N];
int n, m, color[N], pre[N], dist[N];
bool st[N];
vector<pair<int, int>> edges;
void add(int a, int b) {
e[idx] = b, nxt[idx] = h[a], h[a] = idx++;
}
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, nxt[idx] = hs[a], hs[a] = idx++;
}
bool dfs(int u) {
if (color[u])
return color[u] == 2;
color[u] = 2;
if (pre[u] && dfs(pre[u]))
return true;
color[u] = 1;
return false;
}
bool has_cycle() {
memset(color, 0, sizeof color);
for (int i = 1; i <= n; ++i)
if (!color[i] && dfs(i))
return true;
return false;
}
bool spfa(int h[], int src) {
queue<int> q;
q.push(src);
int cnt = 0;
memset(dist, -0x3f, sizeof dist);
dist[src] = 0;
while (q.size()) {
int u = q.front();
q.pop(), st[u] = false;
for (int i = h[u]; i; i = nxt[i]) {
int j = e[i], d = h == hs ? w[i] : 1;
if (dist[j] < dist[u] + d) {
dist[j] = dist[u] + d;
pre[j] = u;
if (++cnt == n + 1) {
cnt = 0;
if (has_cycle())
return true;
}
if (!exchange(st[j], true))
q.push(j);
}
}
}
return has_cycle();
}
signed main() {
#ifndef ONLINE_JUDGE
freopen(".in", "r", stdin); // freopen("a.out", "w", stdout);
#else
cin.tie(0)->sync_with_stdio(0);
#endif
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
add(a, b);
add(b, a, -2);
add(a, b, 1);
edges.push_back({a, b});
}
spfa(h, 1);
// for (int i = n; pre[i]; i = pre[i]) {
// // dist[i] - dist[pre[i]] <= 1
// // dist[pre[i]] >= dist[i] - 1
// add(i, pre[i], -1);
// }
// dist[n] = dist[n]
// dist[n] >= dist[0] + dist[n]
add(n, 1, -dist[n]), add(1, n, dist[n]);
add(1, 0, 0), add(0, 1, 0);
if (spfa(hs, 0))
cout << "No";
else {
cout << "Yes\n";
for (const auto& edge : edges) {
cout << dist[edge.second] - dist[edge.first] << "\n";
}
}
}