图论训练之五

https://www.luogu.org/problem/P1993

差分约束没的说(不会的看我之前写的博客)

  • 1.农场a比农场b至少多种植了c个单位的作物,
  • 2.农场a比农场b至多多种植了c个单位的作物,
  • 3.农场a与农场b种植的作物数一样多。

对于1,可以列出A-B>=c,A>=B+c,建边B--->A,边权为c

对于2,可以列出A-B<=c,B>=A-c,建边A----->B,边权为-c

对于3,可以列出A-B==0,A==B,建边A---->B和B--->A,边权为0

最后还有一个隐藏的条件,即每个农场的值要>=0

所以建一个虚拟的0号农场,向每一条边连边,x[i]-x[0]>=0,即(0,i,0)

最后如果某个点到0号点的最大路径不存在,那就无解了

由于用的是小于等于号,且有负权,直接跑一遍最短路SPFA就好了

code(dfs版的spfa更好):

#include
#define il inline
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
using namespace std;
const int N=50005,inf=23333333;
int n,m,to[N],net[N],w[N],dis[N],cnt,h[N],tot[N];
bool vis[N];

il int gi(){
    int a=0;char x=getchar();
    while(x<'0'||x>'9')x=getchar();
    while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
    return a;
}

il void add(int u,int v,int c){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,w[cnt]=c;}

il bool spfa(int u){
    vis[u]=1;
    for(int i=h[u];i;i=net[i])
        if(dis[to[i]]

你可能感兴趣的:(图论训练之五)