zoukankan      html  css  js  c++  java
  • 【BZOJ】1731: [Usaco2005 dec]Layout 排队布局

    【题意】给定按编号顺序站成一排的牛,给定一些约束条件如两牛距离不小于或不大于某个值,求1和n的最大距离。无解输出-1,无穷解输出-2。

    【算法】差分约束+最短路

    【题解】图中有三个约束条件,依次分析:

    ①坐标顺序和编号顺序一致【一定一定要记得这个约束条件】

    xi-xi-1>=0

    i向-1连边0

    ②两牛距离不大于距离L

    xj-xi<=L

    i向j连边L

    ③两牛距离不小于距离D

    xj-xi>=D即xi-xj<=-D

    j向i连边-D

    连边完毕,通过跑最短路得到起点和终点的直接约束xT-xS<=d,d就是1到n的最大值。

    注意循环队列while(head!=tail)

    检测负环可以用【点的入队次数>n】和【到点步数>n】两种方法。一起用也资瓷=w=。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1010;
    int n,m,k,tot=0;
    int first[maxn],step[maxn],q[maxn],d[maxn];
    bool vis[maxn];
    struct edge{int v,w,from;}e[maxn*maxn];
    void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
    bool spfa(){
        memset(d,0x3f,sizeof(d));
        memset(vis,0,sizeof(vis));
        int head=0,tail=1;
        q[head]=1;vis[1]=1;d[1]=0;
        bool p=1;
        while(head!=tail){//
            int x=q[head++];if(head>n)head=0;
            for(int i=first[x];i;i=e[i].from)if(d[x]+e[i].w<d[e[i].v]){
                d[e[i].v]=d[x]+e[i].w;
                step[e[i].v]=step[x]+1;
                if(step[e[i].v]>n){p=0;break;}
                if(!vis[e[i].v]){
                    if(d[e[i].v]<d[q[head]]){head--;if(head<0)head=n;q[head]=e[i].v;}
                    else{q[tail++]=e[i].v;if(tail>n)tail=0;}
                    vis[e[i].v]=1;
                }
            }
            vis[x]=0;
        }
        return p;
    }
                
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        int u,v,w;
        for(int i=2;i<=n;i++)insert(i,i-1,0);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            if(u>v)swap(u,v);
            insert(u,v,w);
        }
        for(int i=1;i<=k;i++){
            scanf("%d%d%d",&u,&v,&w);
            if(u>v)swap(u,v);
            insert(v,u,-w);
        }
        if(spfa()){
            if(d[n]==0x3f3f3f3f)printf("-2");else printf("%d",d[n]);
        }else printf("-1");
        return 0;
    }
    View Code
  • 相关阅读:
    自己的第一个网页
    第一次爬虫测试
    科学计算与可视化
    python自顶向下的设计方法进行体育竞技分析
    python PIL库的相关操作
    python 关于身份证号码的相关操作
    jieba库
    汉诺塔
    Django项目中运行Scrapy项目
    **Django+Echart实现多个饼状图(echart数据格式问题 {value: 135, name: '视频广告'})
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7690509.html
Copyright © 2011-2022 走看看