算法思想
对于一系列形如的不等式组,要求得是否有解或者解为多少,可以利用求最短路的方法。
将原式变形后得到,类比单源最短路中的对于边u->v(w),,可以连一条b到a的带权边,再在整张图上跑单源最短路。答案就是dis[v]。
例题
#include <bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
using namespace std;
const int N=5E3+10,M=1E4+10;
int n,m,tot;
int dis[N];
string ans;
struct Edge{
int u,v,w;
}e[M];
inline int read()
{
int ret=0;char ch=getchar();
while(ch<'0' || ch>'9')
ch=getchar();
while(ch>='0' && ch<='9')
{
ret=ret*10+ch-'0';
ch=getchar();
}
return ret;
}
void add_edge(int u,int v,int w)
{
e[++tot].u=u;e[tot].v=v;e[tot].w=w;
}
int Bellman_Ford()
{
rep(i,1,n)
{
int flag=0;
rep(j,1,tot)
{
int u=e[j].u,v=e[j].v,w=e[j].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
flag=1;
}
}
if(i==n && flag)
return 0;
}
return 1;
}
int main()
{
n=read();m=read();
int a,b,c,op;
rep(i,1,m)
{
op=read();
switch(op)
{
case 1:a=read();b=read();c=read();add_edge(a,b,-c);break;
case 2:a=read();b=read();c=read();add_edge(b,a,c);break;
case 3:a=read();b=read();add_edge(a,b,0);add_edge(b,a,0);break;
}
}
int flag=Bellman_Ford();
if(flag)
ans="Yes";
else
ans="No";
cout<<ans<<endl;
}