• 【USACO2005Dec】奶牛的站位 Layout


    题目描述

    有 N 头奶牛正在排队,它们的编号为 1 到 N,约翰要给它们安排合适的排队位置,满足以下条 件:

    • 首先,所有奶牛要站在一条直线上。由于是排队,所以编号小的奶牛要靠前,不能让编号大的 奶牛插队。但同一个位置可以容纳多头奶牛,这是因为它们非常苗条的缘故

    • 奶牛喜欢和朋友靠得近点。朋友关系有 F 对,其中第 Ai 头奶牛和第 Bi 头奶牛是第 i 对朋友, 它们的距离不能超过 Ci

    • 奶牛还要和讨厌的同类保持距离。敌对关系有 E 对,其中第 Xi 头奶牛和第 Yi 头奶牛是第 i 对 敌人,它们的距离不能少于 Zi

    你能否帮助约翰找到一个合理的站位方法,满足所有奶牛的要求,而且让 1 号奶牛和 N 号奶牛间的 距离尽量大?

    输入格式

    • 第一行:三个整数 N,F 和 E,2 ≤ N ≤ 1000, 1 ≤ F;E ≤ 10000

    • 第二行到第 F + 1 行:第 i + 1 行有三个整数 Ai,Bi 和 Ci,1 ≤ Ai,Bi ≤ N; 1 ≤ Ci ≤ 10^6

    • 第 F + 2 行到第 F + E + 1 行:第 i + F + 1 行有三个整数 Xi,Yi 和 Zi,1 ≤ Xi,Yi ≤ N; 1 ≤Zi ≤ 10^6

    输出格式

    • 单个整数:如果不存在满足所有条件的安排,输出 −1;如果 1 号奶牛和 N 号奶牛的距离可以 任意大,输出 −2;否则输出 1 号奶牛和 N 号奶牛的最大距离

    样例输入

    4 2 1

    1 3 10

    2 4 20

    2 3 3

    样例输出

    27

    解释

    一号奶牛站在坐标 0,二号奶牛站在坐标 7,

    三号奶牛站在坐标 10,四号奶牛站在坐标 27

    题解

    比较明显的差分约束系统吧。

    根据题目条件很容易得出两个不等式

            min(Ai,Bi)-max(Ai,Bi)>= -Ci

            max(Xi,Yi)-min(Xi,Yi)>= Zi

    根据差分约束系统原理,从min(Ai,Bi)向max(Ai,Bi)引一条权值为Ci的有向边,从max(Xi,Yi)向min(Xi,Yi)引一条权值为Zi的有向边,然后SPFA求最短路就可以了。

    有时为了防止建成的图不连通,常构造一个节点,从这个节点向每个节点连一条边,本题可以不这样。

    dis数组初始化为无穷大,走最短路时,如果有负环,就不存在满足所有条件的安排,输出 −1;如果走完最短路dis[n]还是无穷大,1 号奶牛和 N 号奶牛的距离可以 任意大,输出 −2;不满足以上条件的,直接输出dis[n]。

    #include <cstdio>
    const int N=2005;
    struct node{
        int id,nex,u,w;
    }; 
    node g[40005];
    int fir[1005],num,dis[1005],q[2005],cnt[1005],n;
    bool vis[1005];
    int min(int x,int y)
    {
        return x<=y?x:y;
    }
    int max(int x,int y)
    {
        return x>=y?x:y;
    }
    void add(int x,int y,int z)
    {
        g[++num].u=y;  g[num].w=z;  g[num].nex=fir[x];  fir[x]=num;
    }
    void SPFA()
    {
        int t=1,h=0,i,j,k,v;
        for (i=2;i<=n;i++)
          dis[i]=1e9;
        q[1]=1;  vis[1]=true;
        while (h!=t)
        {
            h=(h+1)%N;
            for (k=fir[q[h]];k;k=g[k].nex)
               if (dis[q[h]]+g[k].w<dis[g[k].u])
              {
                dis[g[k].u]=dis[q[h]]+g[k].w;
                if (!vis[g[k].u])
                {
                    vis[g[k].u]=true;
                    t=(t+1)%N;
                    q[t]=g[k].u;
                    cnt[g[k].u]++;
                    if (cnt[g[k].u]>n)
                    {
                        dis[n]=-1;
                        return;
                    } 
                }
                  
              }
            vis[q[h]]=false;  
        }  
        return;
    }
    int main()
    {
        int F,E,A,B,C,i,j;
        scanf("%d%d%d",&n,&F,&E);
        for (i=1;i<=F;i++)
             scanf("%d%d%d",&A,&B,&C),
          add(min(A,B),max(A,B),C);
    
        for (i=1;i<=E;i++)
          scanf("%d%d%d",&A,&B,&C),
          add(max(A,B),min(A,B),-C);
    
        /*  for (i=1;i<=n;i++)
               add(0,i,0);   */
        SPFA();
        printf("%d",dis[n]!=1e9?dis[n]:-2);
        return 0;  
    }

     

  • 相关阅读:
    在数据库中加字段方法
    【原创】AE套用模板教程
    mysql 在windows server下发生系统错误 1067, 进程意外终止的解决方法
    对unidbgrid的单元格操作
    unigui与uniurlframe的互动
    推荐ajaxfilemanager for tiny_mce 比较完善的tiny_mce编辑器的图片上传及图片管理插件PHP版 支持中文
    html编辑器的调用
    mysqldump导出格式
    Gmail,QMail,163邮箱的 IMAP/SMTP/POP3 地址
    Delphi程序的自动升级功能的实现(AutoUpdate使用指南)
  • 原文地址:https://www.cnblogs.com/rabbit1103/p/8393559.html
Copyright © 2020-2023  润新知