zoukankan      html  css  js  c++  java
  • [USACO05DEC] 布局

    题目描述

    有n头牛,之间有两种限制,一种是距离不超过x,另一种距离不小于x,求1号和n号的最大距离,若不存在方案则输出-1,距离可以无穷大输出-2;

    2N1000,两种限制1MLMD104

    题解

    差分约束裸题;

    要求最大距离,所以最短路?因为好像最短路是从最大值减小直到满足条件,所以最后一定是最大值。

    这道题要注意的地方就是负环可能和1不连通,所以只从1跑spfa可能判不到负环。

    为了判负环就只有建虚拟点向所有点连边,从虚拟点跑spfa判负环。

    最后从1跑spfa求最短路,如果dis[n]没被更新,就说明两个没有约束条件。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    const int oo=2000000000;
    const int maxn=1005;
    const int maxm=21005;
    int n,m1,m2;
    int head[maxn],cnt;
    struct edge{
        int y,next;
        ll val;
    }e[maxm];
    
    template<class T>inline void read(T &x){
        x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    }
    
    void add(int x,int y,ll z){
        e[++cnt]=(edge){y,head[x],z};
        head[x]=cnt;
    }
    
    queue<int> q;
    ll dis[maxn],cx[maxn];
    bool vis[maxn];
    
    void spfa(int s){
        while(!q.empty()) q.pop();
        for(int i=0;i<=n;i++) dis[i]=oo,cx[i]=0,vis[i]=false;
        dis[s]=0;vis[s]=true;cx[s]=1;
        q.push(s);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            vis[x]=false;
            for(int i=head[x];i;i=e[i].next){
                int y=e[i].y;
                if(dis[y]>dis[x]+e[i].val){
                    dis[y]=dis[x]+e[i].val;
                    if(!vis[y]){
                        q.push(y);vis[y]=true;
                        if(++cx[y]>n) {printf("-1");exit(0);}
                    }
                }
            }
        }
    }
    
    int main(){
        read(n);read(m1);read(m2);
        for(int i=1;i<=m1;i++){
            int x,y;
            ll z;
            //dis[y]-dis[x]<=z
            //dis[y]<=dis[x]+z
            read(x);read(y);read(z);
            add(x,y,z);
        }
        for(int i=1;i<=m2;i++){
            int x,y;
            ll z;
            //dis[y]-dis[x]>=z
            //dis[x]<=dis[y]-z
            read(x);read(y);read(z);
            add(y,x,-z);
        }
        for(int i=1;i<=n;i++) add(0,i,0);
        spfa(0);
        spfa(1);
        printf("%lld",dis[n]==oo ? -2 : dis[n]);
    }
    View Code
  • 相关阅读:
    5. 字符串提取
    4.字符串连接
    3. 忽略大小写的字符串比较
    2.Calendar类的使用
    1.==和equals()
    50.使用DOM4J解析XML文件
    C# json提取多层嵌套到数组
    打开SDK Manager检查Android SDK下载和更新失败的解决方法
    (微信API接口开发) 使用HttpWebRequest进行请求时发生错误:基础连接已关闭,发送时发生错误处理
    javascript里面的数组,json对象,动态添加,修改,删除示例
  • 原文地址:https://www.cnblogs.com/sto324/p/11234725.html
Copyright © 2011-2022 走看看