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
  • 相关阅读:
    Codeforces Round 269 (Div. 2)
    Codeforces Round 268 (Div. 2)
    杜教筛
    Codeforces Round 267(Div. 2)
    Codeforces Round 548 (Div. 2)
    Educational Codeforces Round 62 (Rated for Div. 2)
    数据结构编程实验——chapter9-应用二叉树的基本概念编程
    数据结构编程实验——chapter8-采用树结构的非线性表编程
    组合数学及其应用——polya计数
    《A First Course in Abstract Algebra with Applications》-chaper1-数论-棣莫弗定理
  • 原文地址:https://www.cnblogs.com/sto324/p/11234725.html
Copyright © 2011-2022 走看看