zoukankan      html  css  js  c++  java
  • POJ 3169 C

    题意

      有n头奶牛从1到n编号,按照编号顺序站成一排,有可能有多头奶牛站在同一个坐标上。一些奶牛互相喜欢,所以他们的距离不能大于某个距离,一些奶牛互相讨厌,所以他们的距离不能小于某个距离,请计算如果可能的话1到n的最大距离是多少 

    分析

    标准的差分约束的裸题。题中的条件可以做如下转化

    1.A和B的距离不得超过x:  B-A<=x

    2.C和D的距离不得小于y:C-D>=y也就是D-C<=-y

    3.奶牛按照编号顺序排序:位置 pos[i+1]-pos[i]>=0也就是pos[i]-pos[i+1]<=0

    这样把关系全部变成了小于关系,求最大距离的话建图以后跑一个最短路就行。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <queue>
     6 
     7 using namespace std;
     8 const int maxn=1000+10;
     9 const int maxm=40000+10;
    10 const int INF=2147000000;
    11 
    12 int head[maxn],Next[maxm],to[maxm],val[maxm];
    13 int n,ml,md,sz;
    14 void add_edge(int a,int b,int w){
    15     ++sz;
    16     to[sz]=b;
    17     val[sz]=w;
    18     Next[sz]=head[a];
    19     head[a]=sz;
    20 }
    21 int a,b,w;
    22 int spfa(){
    23     int d[maxn],vis[maxn],cnt[maxn];
    24     memset(vis,0,sizeof(d));
    25     memset(cnt,0,sizeof(cnt));
    26     for(int i=0;i<=n;i++)d[i]=INF;
    27     queue<int>q;
    28     q.push(n);
    29     d[n]=0;vis[n]=1;cnt[n]=1;
    30     while(!q.empty()){
    31         int u=q.front();q.pop();vis[u]=0;
    32     //    cout<<u<<endl;
    33         for(int i=head[u];i;i=Next[i]){
    34             int v=to[i];
    35             if(d[v]>d[u]+val[i]){
    36                 d[v]=d[u]+val[i];
    37                 if(!vis[v]){
    38                     vis[v]=1;
    39                     q.push(v);
    40                     cnt[v]++;
    41                     if(cnt[v]>n){
    42                         return -1;
    43                     }
    44                 }
    45             }
    46         }
    47     }
    48     if(d[1]==INF)
    49         return -2;
    50     return d[1];
    51 }
    52 int main(){
    53     scanf("%d%d%d",&n,&ml,&md);
    54     for(int i=1;i<=ml;i++){
    55         scanf("%d%d%d",&a,&b,&w);
    56         add_edge(b,a,w);
    57     }
    58     for(int i=1;i<=md;i++){
    59         scanf("%d%d%d",&a,&b,&w);
    60         add_edge(a,b,-w);
    61     }
    62     for(int i=1;i<n;i++){
    63         add_edge(i,i+1,0);
    64     }
    65     int ans=spfa();
    66     printf("%d",ans);
    67 
    68 return 0;
    69 }
    View Code
  • 相关阅读:
    shell脚本编程-结构化命令3-while、until命令
    shell脚本编程-结构化命令2-for命令
    sscanf解析复杂字符串,双引号通配符的使用问题
    shell脚本编程-结构化命令1-分支语句
    shell脚本编程基础
    linux系统管理的基本命令2
    linux系统管理的基本命令
    redis
    Eclipse启动报错
    java斗地主发牌源码
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8893099.html
Copyright © 2011-2022 走看看