zoukankan      html  css  js  c++  java
  • poj 3159 Candies

    差束约分

    有人将这题归为最短路的中等题,所以做一下,但是发现其实是裸的差束约分

    题意:n个人,m个信息,每行的信息是3个数字,A,B,C,表示B比A多出来的糖果不超过C个,问你,n号人最多比1号人多几个糖果

    m行信息,所以得到m个不等式  :  XB - XA <= C , 所有不等式加起来就是一个差束约分系统

    对应最短路模型,一开始是  d[v] >= d[u]+w  (有向边u--->v)  , 在进行完最短路后则变为  d[v] <= d[u] + w  ,转化为  d[v] - d[u] <= w

    这个和上面的 XB - XA <= C 是相同的模式 , 因此建图的时候有向边应该是 A----->B , 边权为C

    所以我们是要求  max( Xn - X1) , 可知是  Xn - X1 <= res  令其取最大值,就是 Xn - X1 = res

    所以以1为源点,n为汇点,运行一次最段落即可

    没有负权,所以spfa和dij都可以

    另外这题长见识了,用spfa+queue是会超时的,用spfa+stack则500ms。另外写成spfa的dfs搜索式也是会超时的,所以这也验证了spfa很不稳定

    同样的,朴素的dij是会超时的,要用堆优化,即优先队列版本的dij

    下面只给出spfa+stack(迭代版本,模拟dfs,但是dfs居然超时)的代码

    #include <cstdio>
    #include <cstring>
    #include <stack>
    #include <vector>
    using namespace std;
    #define N 30010
    #define M 150010
    #define INF 0x3f3f3f3f
    
    int head[N];
    struct edge
    {
       int u,v,w,next;
    }e[M];
    int d[N];
    int n,tot;
    bool ins[N];
    
    void add(int u ,int v ,int w)
    {
       e[tot].u = u; e[tot].v = v; e[tot].w = w;
       e[tot].next = head[u]; head[u] = tot++;
    }
    
    void spfa(int s, int t)
    {
       stack<int>sta;
       memset(d,0x3f,sizeof(d));
       memset(ins,false,sizeof(ins));
       while(!sta.empty()) sta.pop();
       d[s] = 0;
       sta.push(s);
       ins[s] = true;
       while(!sta.empty())
       {
          int u,v,w;
          u = sta.top();
          sta.pop();
          ins[u] = false;
          for(int k=head[u]; k!=-1; k=e[k].next)
          {
             v = e[k].v;
             w = e[k].w;
             if(d[u]+w < d[v])
             {
                d[v] = d[u] + w;
                if(!ins[v])
                {
                   sta.push(v);
                   ins[v] = true;
                }
             }
          }
       }
       printf("%d\n",d[t]);
    }
    
    int main()
    {
       int n,m;
       scanf("%d%d",&n,&m);
       //while(scanf("%d%d",&n,&m)!=EOF)
       //{
          tot = 0;
          memset(head,-1,sizeof(head));
          for(int i=0; i<m; i++)
          {
             int u,v,w;
             scanf("%d%d%d",&u,&v,&w);
             add(u,v,w);
          }
          spfa(1,n);
       //}
       return 0;
    }
  • 相关阅读:
    HDU 1584 蜘蛛牌(DFS)
    HDU 1800 Flying to the Mars(贪心)
    zsh: command not found: java (xxx)
    Deepin20安装Mysql8
    Deepin全局菜单
    Ubuntu PPA 解读
    Node安装与配置
    Windows安装配置Maven
    idea 安装 Vue 插件没有Vue component选项
    Linux桌面系统创建应用程序快捷方式
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3051472.html
Copyright © 2011-2022 走看看