zoukankan      html  css  js  c++  java
  • poj3159Candies(差分约束)

    题目链接:http://poj.org/problem?id=3159

    之前做过一次,然而这次又做了好久。还是不熟练啊。

    spfa有时用stack比用queue快。比如这题,用queue就超时,用stack就可以过。

    至于为什么好像也说不清,反正都是xjb搞出来的。。。。。。

    自己稍微总结一下差分约束吧,发现不管别人写的多好,看的不管多明白,如果自己不写下来,很快就会忘。。。

    理解还不够,随便写写,只是给自己巩固一下。

    大神写的在这里:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html

    差分约束:

    一:求最大值,转换成求最短路。

    给定不等式 A-B<=C;

    步骤如下:

    既然是求最短路,肯定要用到过程中最重要的【松弛操作】,即

    if(dis[v]>dis[u]+w)   dis[v]=dis[u]+w;

    这一步的目的是尽量使dis[v]<=dis[u]+w;

    由此我们可把上面的不等式转化成类似的形式,即A<=B+C;(注意此处C可能是负值)

    建立一条B到A边权为C的路,然后进行最短路即可。

    二:求最小值,转换成求最长路。

    基本和第一种相同。

    不过是将不等式装换成B>=A-C;(再说一次C是带符号运算的!)

    为了松弛操作时 if(dis[B]<dis[A]-C) dis[B]=dis[A]-C; 

    下面是本题的代码。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<stack>
     4 using namespace std;
     5 const int maxn=30010;
     6 const int maxe=150010;
     7 const int maxx=0x3f3f3f3f;
     8 int dis[maxn];
     9 int head[maxn];
    10 int ins[maxn];
    11 int cnt=0;
    12 
    13 int n,m;
    14 int u,v,w;
    15 
    16 stack<int> sta;
    17 struct edge
    18 {
    19     int v,w,nex;
    20 }e[maxe];
    21 
    22 void add(int u,int v,int w)
    23 {
    24     e[cnt].v=v;
    25     e[cnt].w=w;
    26     e[cnt].nex=head[u];
    27     head[u]=cnt++;
    28 }
    29 
    30 int spfa(int s)
    31 {
    32     for(int i=0;i<=n;i++)
    33     {
    34         dis[i]=maxx;
    35         ins[i]=0;
    36     }
    37     dis[1]=0;
    38     ins[1]=1;
    39     sta.push(1);
    40     while(!sta.empty())
    41     {
    42         int u=sta.top();
    43         sta.pop();
    44         ins[u]=0;  //
    45         for(int i=head[u];i!=-1;i=e[i].nex)
    46         {
    47             int v=e[i].v,w=e[i].w;
    48             if(dis[v]>dis[u]+w)
    49             {
    50                 dis[v]=dis[u]+w;
    51                 if(!ins[v])
    52                 {
    53                     ins[v]=1;
    54                     sta.push(v);
    55                 }
    56             }
    57         }
    58     }
    59     return dis[n];
    60 }
    61 int main()
    62 {
    63     while(scanf("%d%d",&n,&m)!=EOF)
    64     {
    65         cnt=0;
    66         memset(head,-1,sizeof(head));
    67         for(int i=0;i<m;i++)
    68         {
    69             scanf("%d%d%d",&u,&v,&w);
    70             add(u,v,w);
    71         }
    72         printf("%d
    ",spfa(1));
    73     }
    74 }
  • 相关阅读:
    mariadb
    Linux下安装配置virtualenv与virtualenvwrapper
    配置安装源
    Redis哨兵
    Android 常用工具类之DeviceInfoUtil
    Android 常用工具类之RuntimeUtil
    android 中的几种目录
    listview 滑动以后设置最上面一行为整行展示
    Android 常用工具类之SPUtil,可以修改默认sp文件的路径
    android 在应用中切换语言
  • 原文地址:https://www.cnblogs.com/yijiull/p/6624187.html
Copyright © 2011-2022 走看看