这是一道差分约束的小清新题,不需要求出差分约束的解,那么直接上DFS大力判断负环即可,有负环就无解嘛。
(Code:)
#include<bits/stdc++.h>
#define re register
#define ll long long
#define MAX(A,B) (A>B?A:B)
#define MIN(A,B) (A>B?B:A)
using namespace std;
const int maxn=1e5+5;
inline int read(){
char ch=getchar();
int r=0,s=1;
while(ch>57||ch<48)s=ch==45?0:s,ch=getchar();
while(ch>=48&&ch<=57)r=(r<<1)+(r<<3)+(ch^48),ch=getchar();
return s?r:-r;
}
struct edge{int to,nxt,w;}e[maxn*3];
int n,m,cnt,pd,times,top;
int head[maxn],dfn[maxn],low[maxn],sum[maxn],in[maxn],stk[maxn];
void add(int u,int v,int w){e[++cnt]=(edge){v,head[u],w},head[u]=cnt;return;}
void dfs(int u,int dis){
dfn[u]=low[u]=++times;
stk[++top]=u,sum[top]=dis;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!dfn[v])dfs(v,e[i].w);
low[u]=MIN(low[u],low[v]);
}
if(dfn[u]==low[u]){
int res=0;
while(stk[top]!=u){
res+=sum[top];
--top;
}
--top;
if(res<0){puts("No");exit(0);}
}
return;
}
int main(){
n=read(),m=read();
for(re int i=1,k,a,b,c;i<=m;++i){
k=read();
switch(k){
case 1:a=read(),b=read(),c=read(),add(a,b,-c);break;
case 2:a=read(),b=read(),c=read(),add(b,a,c);break;
case 3:a=read(),b=read(),add(a,b,0),add(b,a,0);break;
default:break;
}
}
for(int i=1;i<=n;++i){
if(!dfn[i])dfs(i,0);
}
puts("Yes");
return 0;
}
这竟然会是蓝题?