• [bzoj1731] [Usaco2005 dec]Layout 排队布局


      差分约束系统。。。因为题目要求的是1和n的最大距离所以这题就跑最长路。。

      对于互相反感的牛(i与j互相反感,彼此距离至少为len,i<j)就有dis[j]-dis[i]>=len。就加一条i->j,长度为len的边。

      有好感的牛(i与j有好感,彼此距离至多len,i<j),就有dis[j]-dis[i]<=len;但因为我们跑的是最长路,所以得改成dis[i]-dis[j]>=-len的形式,就加一条j->i,长度-len的边。

      又因为牛是按编号站成一列。。所以dis[i+1]-dis[i]>=0。也就是连一条i->i+1,长度为0的边(1<=i<n)。

      如果有正权环的话就无解,如果从点n无法走到点1,也就是说n和1之间没有什么约束,那么1和n距离可以无穷大。。。

      其实也可以把权值取反然后跑最短路。。虽然都一样= =

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=1023;
     6 struct zs{
     7     int too,pre,dis;
     8 }e[23333];
     9 int last[maxn],dis[maxn],dl[maxn],tot;
    10 int i,n,m1,m2,a,b,c,l,r,now;
    11 bool u[maxn],ins[maxn],flag;
    12 int ra;char rx;
    13 inline int read(){
    14     rx=getchar();ra=0;
    15     while(rx<'0'||rx>'9')rx=getchar();
    16     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    17 }
    18 inline void insert(int a,int b,int c){
    19     e[++tot].too=b;e[tot].dis=c;e[tot].pre=last[a];last[a]=tot;
    20 }
    21 void dfs(int x){
    22     ins[x]=1;
    23     for(int i=last[x],to=e[i].too;i&&!flag;i=e[i].pre,to=e[i].too)if(dis[to]<dis[x]+e[i].dis){
    24         dis[to]=dis[x]+e[i].dis;if(ins[to]){flag=1;return;}
    25         dfs(to);
    26     }
    27     ins[x]=0;
    28 }
    29 int main(){
    30     n=read();m1=read();m2=read();
    31     for(i=1;i<n;i++)insert(i,i+1,0);
    32     for(i=1;i<=m1;i++){
    33         a=read();b=read();c=read();
    34         if(a>b)swap(a,b);
    35         insert(b,a,-c);
    36     }
    37     for(i=1;i<=m2;i++){
    38         a=read();b=read();c=read();if(a>b)swap(a,b);
    39         insert(a,b,c);
    40     }
    41     l=0;r=1;dl[1]=n;u[n]=1;
    42     while(l<r){
    43         now=dl[++l];
    44         for(i=last[now];i;i=e[i].pre)if(!u[e[i].too])
    45         dl[++r]=e[i].too,u[e[i].too]=1;
    46     }
    47     if(!u[1]){puts("-2");return 0;}
    48     memset(dis,188,sizeof(dis));dis[n]=0;
    49     dfs(n);
    50     if(flag){puts("-1");return 0;}
    51     printf("%d
    ",-dis[1]);
    52     return 0;
    53 }
    View Code

      为啥dfs版的spfa会比kpm写的队列版慢20倍。。。。。。。。。。。也许是数据很少有无解情况吧。。

  • 相关阅读:
    对进程空间的认识
    自己实现智能指针
    实现一个string类
    常见问题总结
    pong game using ncurses
    知识梳理
    经典算法回顾
    自己实现more命令
    表的垂直拆分和水平拆分-zz
    MySQL索引原理及慢查询优化-zz
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5072819.html
Copyright © 2020-2023  润新知