RT,蒟蒻做完本题后去做了一道站外题,该站外题除 n,m 分别扩大到了 <500 和 <5000 以外和本题没有任何区别。
#include <bits/stdc++.h>
#define N 500
#define M 12000
#define INF 1145141919810114514
#define int1 long long
using namespace std;
int1 t,n,m,x,y,z,i;
bool inq[N + 5];
int1 cnt[N + 5],dis[N + 5];
int1 hea[N + 5],nex[M + 5],to[M + 5],w[M + 5],bs;
int1 read(){
int1 x = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)){
if(ch == '-'){
f = -1;
}
ch = getchar();
}
while(isdigit(ch)){
x = (x << 1) + (x << 3) + (ch ^ '0');
ch = getchar();
}
return x * f;
}
char getc(int1 x){//1:数字 2:小写 4:大写 8:字符 16:空格
char ch = getchar();
while(!(((x & 1) && ch >= '0' && ch <= '9') || ((x & 2) && ch >= 'a' && ch <= 'z') ||
((x & 4) && ch >= 'A' && ch <= 'Z') || ((x & 8) && ch != ' ' && ch != '\n' && ch != '\0') || ((x & 16) && ch != '\n' && ch != '\0'))){
ch = getchar();
}
return ch;
}
void uprint(int1 x){
if(x > 9){
uprint(x / 10);
}
putchar(x % 10 ^ 48);
return ;
}
void print(int1 x){
if(x < 0){
putchar('-');
x = -x;
}
uprint(x);
return ;
}
void ps(int1 x){
print(x);
putchar(' ');
return ;
}
void pe(int1 x){
print(x);
putchar('\n');
return ;
}
void add_edge(int1 x,int1 y,int1 z){
nex[++bs] = hea[x],hea[x] = bs,to[bs] = y,w[bs] = z;
return ;
}
bool solve(){
n = read() + 1,m = read();
for(i = 1; i <= m; i++){
x = read() - 1,y = read(),z = read();
add_edge(x,y,z);
add_edge(y,x,-z);
}
for(i = 0; i < n; i++){
cnt[i] = 0,dis[i] = -INF,inq[i] = 0;
add_edge(n,i,0);
}
queue<int1> q;
dis[n] = 0;
inq[n] = 1;
q.push(n);
while(!q.empty()){
int1 now = q.front();
q.pop();
inq[now] = 0;
for(int1 i = hea[now]; i; i = nex[i]){
int1 nxt = to[i];
if(dis[now] + w[i] > dis[nxt]){
dis[nxt] = dis[now] + w[i];
cnt[nxt] = cnt[now] + 1;
if(cnt[nxt] >= n){
return 0;
}
if(!inq[nxt]){
//inq[nxt] = 1;
q.push(nxt);
}
}
}
}
return 1;
}
int main(){
t = read();
while(t--){
bs = 0;
for(i = 0; i <= n; i++){
hea[i] = 0;
}
if(solve()){
printf("true\n");
}else{
printf("false\n");
}
}
return 0;
}
注意到SPFA中有一行注释(节点入队时打标记),这理应是SPFA中的关键代码(吧?),但是我的代码加上这一行会T得很惨,去掉这一行反而能AC……
(不过无论我的代码里有没有这一行,都能AC本题)
所以这到底是为什么啊qaq