我知道这题 SPFA 会被卡,但是为什么会有 WA 的点,想知道哪错了。思路是差分约束跑最短路。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
bool START_MEMORY;
const int N = 1e5 + 5;
const ll inf = 1e18;
int n, m;
vector <pair <int, ll> > G[N];
queue <int> q;
ll dis[N];
int cnt[N];
bool vis[N], flag = true;
void spfa(){
for(int i = 1; i <= n; i++) dis[i] = inf;
q.push(0);
vis[0] = true;
cnt[0] = 1;
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(auto [v, w] : G[u]){
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
if(!vis[v]){
q.push(v);
vis[v] = true;
if(++cnt[v] > n + 1){
flag = false;
return;
}
}
}
}
}
}
void Solve(){
cin >> n >> m;
int op, a, b;
for(int i = 1; i <= m; i++){
cin >> op >> a >> b;
if(op == 1){ // a = b -> (a <= b + 0 and b <= a + 0)
G[b].push_back(make_pair(a, 0));
G[a].push_back(make_pair(b, 0));
}else if(op == 2){ // a < b -> a <= b + (-1)
G[b].push_back(make_pair(a, -1));
}else if(op == 3){ // a >= b -> b <= a + 0
G[a].push_back(make_pair(b, 0));
}else if(op == 4){ // a > b -> b <= a + (-1)
G[a].push_back(make_pair(b, -1));
}else{ // a <= b -> a <= b + 0
G[b].push_back(make_pair(a, 0));
}
}
for(int i = 1; i <= n; i++) G[0].push_back(make_pair(i, 0));
spfa();
if(!flag) cout << -1 << "\n";
else{
ll ans = 0, mn = inf;
for(int i = 1; i <= n; i++) mn = min(mn, dis[i]);
mn = -mn + 1;
mn = max(mn, 0ll);
for(int i = 1; i <= n; i++) ans += dis[i] + mn;
cout << ans << "\n";
}
}
bool END_MEMORY;
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T = 1;
// cin >> T;
while(T--) Solve();
cerr << "Time: " << 1000 * clock() / CLOCKS_PER_SEC << " ms\n";
cerr << "Memory: " << fixed << setprecision(3) << double(&END_MEMORY - &START_MEMORY) / 1024 << " KB\n";
return 0;
}