题目:BZOJ3436
解析:
差分约束系统。
分析一下三种情况:
1.农场
a
a
a比农场
b
b
b至少多种植了
c
c
c个单位的作物
即
a
≥
b
+
c
−
>
b
≤
a
−
c
a\geq b+c->b\leq a-c
a≥b+c−>b≤a−c,
a
a
a向
b
b
b连一条长度为
−
c
-c
−c的单向边。
2.农场
a
a
a比农场
b
b
b至多多种植了
c
c
c个单位的作物。
即
a
≤
b
+
c
a\leq b+c
a≤b+c,
b
b
b向
a
a
a连一条长度为
c
c
c的单向边。
3.农场
a
a
a与农场
b
b
b种植的作物数一样多。
即
a
=
b
−
>
a
≤
b
a=b->a\leq b
a=b−>a≤b且
b
≥
a
b\geq a
b≥a,
a
,
b
a,b
a,b之间连一条长度为
0
0
0的双向边。
然后跑SPFA最短路判负环就行了,注意这道题
B
F
S
BFS
BFS会
T
T
T,
D
F
S
DFS
DFS才能过。
代码(BFS):
#include <bits/stdc++.h>
using namespace std;
const int Max=10005;
int n,m,size;
int first[Max],sum[Max],v[Max],dis[Max];
struct shu{int to,next,len;}e[Max<<2];
inline int get_int()
{
int x=0,f=1;char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline void build(int x,int y,int z)
{
e[++size].next=first[x],first[x]=size,e[size].to=y,e[size].len=z;
}
inline bool SPFA()
{
queue<int>q;
memset(dis,0x3f,sizeof(dis));
q.push(0),sum[0]++,dis[0]=0;
while(q.size())
{
int p=q.front();q.pop();v[p]=0;
for(int u=first[p];u;u=e[u].next)
{
int to=e[u].to;
if(dis[to]>dis[p]+e[u].len)
{
dis[to]=dis[p]+e[u].len;
if(!v[to])
{
sum[to]++;
if(sum[to] >= n) return 0;
v[to] = 1,q.push(to);
}
}
}
}
return 1;
}
int main()
{
n=get_int(),m=get_int();
while(m--)
{
int tag=get_int(),x=get_int(),y=get_int(),z;
if(tag==1) z=get_int(),build(x,y,-z);
if(tag==2) z=get_int(),build(y,x,z);
if(tag==3) build(x,y,0),build(y,x,0);
}
for(int i=1;i<=n;i++) build(0,i,0);
if(SPFA()) puts("Yes");
else puts("No");
return 0;
}
代码(DFS):
#include <bits/stdc++.h>
using namespace std;
const int Max=10005;
int n,m,size,flag;
int first[Max],sum[Max],v[Max],dis[Max];
struct shu{int to,next,len;}e[Max<<2];
inline int get_int()
{
int x=0,f=1;char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline void build(int x,int y,int z)
{
e[++size].next=first[x],first[x]=size,e[size].to=y,e[size].len=z;
}
inline void SPFA(int p)
{
v[p]=1;
for(int u=first[p];u;u=e[u].next)
{
int to=e[u].to;
if(dis[to]>dis[p]+e[u].len)
{
if(v[to]) {flag=1;return;}
dis[to]=dis[p]+e[u].len;
SPFA(to);
}
}
v[p]=0;
}
int main()
{
n=get_int(),m=get_int();
while(m--)
{
int tag=get_int(),x=get_int(),y=get_int(),z;
if(tag==1) z=get_int(),build(x,y,-z);
if(tag==2) z=get_int(),build(y,x,z);
if(tag==3) build(x,y,0),build(y,x,0);
}
for(int i=1;i<=n;i++) build(0,i,0);
memset(dis,0x3f,sizeof(dis)),dis[0]=0;
SPFA(0);
if(!flag) puts("Yes");
else puts("No");
return 0;
}