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 }
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    22. Generate Parentheses (backTracking)
    21. Merge Two Sorted Lists
    20. Valid Parentheses (Stack)
    19. Remove Nth Node From End of List
    18. 4Sum (通用算法 nSum)
    17. Letter Combinations of a Phone Number (backtracking)
    LeetCode SQL: Combine Two Tables
    LeetCode SQL:Employees Earning More Than Their Managers
  • 原文地址:https://www.cnblogs.com/yijiull/p/6624187.html
Copyright © 2011-2022 走看看