题目:
题解:新知识了差分约束
学会了就会发现这题是个裸题。
这里提出hin重要的几句话
对于每个不等式 x[i] - x[j] <= a[k],对结点 j 和 i 建立一条 j -> i的有向边,边权为a[k],求x[n-1] - x[0] 的最大值就是求 0 到n-1的最短路。
如果这个建图中有负环,说明不存在,可以用SPFA判断有无负环。此题一定使用SPFA的DFS形式,因为SPFA的BFS判断负环最坏复杂度为O(N^2)而DFS只有O(N),所以用BFS会TLE。
没有用longlong会T???
代码:
#include <cstdio>
#include <cstring>
#define N 20005
#define LL long long
using namespace std;
int tot,nxt[N],point[N],v[N],cc[N],n;
LL dis[N];
bool vis[N];
void addline(int x,int y,int cap){++tot; nxt[tot]=point[x];point[x]=tot; v[tot]=y; cc[tot]=cap;}
bool spfa(int now)
{
vis[now]=1;
for (int i=point[now];i;i=nxt[i])
if (dis[v[i]]>dis[now]+cc[i])
{
dis[v[i]]=dis[now]+cc[i];
if (vis[v[i]]) return 0;
else if (!spfa(v[i])) return 0;
}
vis[now]=0;
return 1;
}
int main()
{
int m,i;
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++)
{
int id,a,b,c;
scanf("%d",&id);
if (id==1)
{
scanf("%d%d%d",&a,&b,&c);
addline(a,b,-c);
}
if (id==2)
{
scanf("%d%d%d",&a,&b,&c);
addline(b,a,c);
}
if (id==3)
{
scanf("%d%d",&a,&b);
addline(a,b,0); addline(b,a,0);
}
}
for (i=1;i<=n;i++) addline(0,i,0);
memset(dis,0x7f,sizeof(dis));
dis[0]=0;
if (spfa(0)) printf("Yes");
else printf("No");
}