zoukankan      html  css  js  c++  java
  • 图论训练之五

    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-B0,AB,建边A---->B和B--->A,边权为0

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

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

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

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

    code(dfs版的spfa更好):

    #include<bits/stdc++.h>
    #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]]<dis[u]+w[i]){
                dis[to[i]]=dis[u]+w[i];
                if(vis[to[i]])return 0;
                if(!spfa(to[i]))return 0;
            }
        vis[u]=0;
        return 1;
    }
    
    int main(){
        n=gi(),m=gi();
        int f,a,b,c;
        while(m--){
            f=gi(),a=gi(),b=gi();
            if(f==1)c=gi(),add(b,a,c);
            else if(f==2)c=gi(),add(a,b,-c);
            else if(f==3)add(a,b,0),add(b,a,0);
        }
        For(i,1,n)add(0,i,0),dis[i]=-inf;
        if(!spfa(0))cout<<"No";
        else cout<<"Yes";
        return 0;
    }
    
  • 相关阅读:
    好用的电脑软件
    Swoft HTTPServer 使用经验分享
    nginx location proxy_pass详解
    kafka文档
    es 安装
    rabbitmq 文档
    Mysql百万级数据迁移,怎么迁移?实战过没?
    用bat脚本在Windows上实现微信多开
    vscode保存时自动格式化
    引入bootstrap
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11626472.html
Copyright © 2011-2022 走看看