看到题就可以想到差分约束
判断负环要用dfs,bfs-spfa会TLE 4个点
bfs-spfa
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = ;
const int MAXM = ;
int cnt=,u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
bool vis[MAXN];
int inq[MAXN],dis[MAXN],f[MAXN];
int n,m;
void addedge(int ux,int vx,int wx){
++cnt;
u[cnt]=ux;
v[cnt]=vx;
w[cnt]=wx;
next[cnt]=first[ux];
first[ux]=cnt;
}
bool spfa(int s,int t){
queue<int> q;
for(int i=;i<=n+;i++){
dis[i]=0x3f3f3f3f;
}
q.push(s);
dis[s]=;
inq[s]=;
vis[s]=;
f[s]=;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=;
f[u]=;
for(int i=first[u];i;i=next[i]){
if(w[i]+dis[u]<dis[v[i]]){
dis[v[i]]=w[i]+dis[u];
if(!vis[v[i]]){
vis[v[i]]=;
inq[v[i]]++;
q.push(v[i]);
if(inq[v[i]]>n)
return false;
}
}
}
}
return true;
}
int main(){
cin>>n>>m;
int a,b,c,mode;
for(int i=;i<=m;i++){
cin>>mode;
if(mode==){
cin>>a>>b>>c;
addedge(a,b,-c);
}
else if(mode==){
cin>>a>>b>>c;
addedge(b,a,c);
}
else{
cin>>a>>b;
addedge(a,b,);
addedge(b,a,);
}
}
for(int i=;i<=n;i++)
if(!f[i])
if(!spfa(i,)){
printf("No\n");
return ;
}
printf("Yes\n");
return ;
}
dfs-spfa
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = ;
const int MAXM = ;
int cnt=,u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
int vis[MAXN];
int inq[MAXN],dis[MAXN],f[MAXN];
int n,m;
void addedge(int ux,int vx,int wx){
++cnt;
u[cnt]=ux;
v[cnt]=vx;
w[cnt]=wx;
next[cnt]=first[ux];
first[ux]=cnt;
}
bool flag=false;
void spfa(int ux){
vis[ux]=;
for(int i=first[ux];i;i=next[i]){
if(dis[ux]+w[i]<dis[v[i]]){
if(vis[v[i]]){
flag=true;
return;
}
dis[v[i]]=dis[ux]+w[i];
spfa(v[i]);
}
}
vis[ux]=;
return;
}
int main(){
cin>>n>>m;
int a,b,c,mode;
for(int i=;i<=m;i++){
cin>>mode;
if(mode==){
cin>>a>>b>>c;
addedge(a,b,-c);
}
else if(mode==){
cin>>a>>b>>c;
addedge(b,a,c);
}
else{
cin>>a>>b;
addedge(a,b,);
addedge(b,a,);
}
}
for(int i=;i<=n;i++){
dis[i]=;
spfa(i);
if(flag){
printf("No\n");
return ;
}
}
printf("Yes\n");
return ;
}