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

    很好的讲解: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; 

    上面都是最简单的线性约束的情况。。复杂一些的还不是很理解,等学好了再补。

    Layout

     POJ - 3169

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn=1010;
     6 const int maxe=20010;
     7 const int inf=0x3f3f3f3f;
     8 int n,m,c;
     9 int u,v,w;
    10 struct edge
    11 {
    12     int v,w,nex;
    13 }e[maxe];
    14 int head[maxn],ins[maxn],sta[maxn],dis[maxn];
    15 int cnt;
    16 
    17 void add(int u,int v,int w)
    18 {
    19     e[cnt].v=v;
    20     e[cnt].w=w;
    21     e[cnt].nex=head[u];
    22     head[u]=cnt++;
    23 }
    24 
    25 int spfa(int s)
    26 {
    27     for(int i=1;i<=n;i++)
    28     {
    29         dis[i]=inf;
    30         ins[i]=0;
    31     }
    32     dis[s]=0;
    33     ins[s]=1;
    34     int top=0;
    35     sta[top++]=s;
    36     while(top)
    37     {
    38         int u=sta[--top];
    39         for(int i=head[u];i!=-1;i=e[i].nex)
    40         {
    41             int v=e[i].v;
    42             int w=e[i].w;
    43             if(ins[v]==n) return -1;  //入队>=n次;说明存在负环
    44             if(dis[v]>dis[u]+w)
    45             {
    46                 dis[v]=dis[u]+w;
    47                 ins[v]++;
    48                 sta[top++]=v;
    49             }
    50         }
    51     }
    52     if(dis[n]==inf) return -2;   //说明不可达
    53     else return dis[n];
    54 }
    55 
    56 int main()
    57 {
    58     while(scanf("%d%d%d",&n,&m,&c)!=EOF)
    59     {
    60         memset(head,-1,sizeof head);
    61         cnt=0;
    62         for(int i=0;i<m;i++)
    63         {
    64             scanf("%d%d%d",&u,&v,&w);  //d[v]-d[u]<=w  ->   d[v]<=d[u]+w  ->   if:  d[v]>d[u]+w
    65             if(u>v) swap(u,v);
    66             add(u,v,w);
    67         }
    68         for(int i=0;i<c;i++)
    69         {
    70             scanf("%d%d%d",&u,&v,&w);   //  d[v]-d[u]>=w  ->  d[u]<=d[v]-w  ->  if: d[u]>d[v]-w
    71             if(u>v) swap(u,v);
    72             add(v,u,-w);
    73 
    74         }
    75         printf("%d
    ",spfa(1));
    76 
    77 
    78     }
    79     return 0;
    80 }
    View Code

    Candies

     POJ - 3159

     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 }
    View Code
     

    Halum

     UVA - 11478 
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 const int maxv=510;
      5 const int maxe=3000;
      6 #define CLR(m,a) memset(m,a,sizeof(m))
      7 
      8 struct Edge
      9 {
     10     int v,w,nex;
     11 }e[maxe];
     12 int head[maxv];
     13 int cnt=0;
     14 void init()
     15 {
     16     CLR(head,-1);
     17     cnt=0;
     18 }
     19 void add(int u,int v,int w)
     20 {
     21     e[cnt].v=v;
     22     e[cnt].w=w;
     23     e[cnt].nex=head[u];
     24     head[u]=cnt++;
     25 }
     26 int n,m;
     27 
     28 int inq[maxv],dis[maxv],deg[maxv];
     29 int bellman()
     30 {
     31     queue<int> q;
     32     CLR(dis,inf);
     33     CLR(inq,0);
     34     CLR(deg,0);
     35     for(int i=0;i<n;i++){
     36         q.push(i); dis[i]=0; inq[i]=1; deg[i]=1;
     37     }
     38     while(!q.empty()){
     39         int u=q.front();
     40         q.pop();
     41         inq[u]=0;
     42         for(int i=head[u];~i;i=e[i].nex){
     43             int v=e[i].v;
     44             if(dis[v]>dis[u]+e[i].w){
     45                 dis[v]=dis[u]+e[i].w;
     46                 if(!inq[v]){
     47                     inq[v]=1;
     48                     q.push(v);
     49                     if(++deg[v]>=n) return 1;
     50                 }
     51             }
     52         }
     53     }
     54     return 0;
     55 }
     56 int check(int x)
     57 {
     58     int ok=1;
     59     for(int i=0;i<n;i++){
     60         for(int j=head[i];~j;j=e[j].nex){
     61             e[j].w-=x;
     62         }
     63     }
     64     if(bellman()) ok=0;
     65     for(int i=0;i<n;i++){
     66         for(int j=head[i];~j;j=e[j].nex){
     67             e[j].w+=x;
     68         }
     69     }
     70     return ok;
     71 }
     72 int main()
     73 {
     74     while(scanf("%d%d",&n,&m)!=EOF){
     75         init();
     76         int u,v,w;
     77         int maxw=0;
     78         for(int i=0;i<m;i++){
     79             scanf("%d%d%d",&u,&v,&w);
     80             u--;v--;
     81             add(u,v,w);
     82             maxw=max(maxw,w);
     83         }
     84         if(check(maxw+1)){
     85             puts("Infinite");
     86             continue;
     87         }
     88         if(!check(1)){
     89             puts("No Solution");
     90             continue;
     91         }
     92         int L=2,R=maxw;
     93         while(L<=R){
     94             int m=L+(R-L)/2;
     95             if(check(m)) L=m+1;
     96             else R=m-1;
     97         }
     98         printf("%d
    ",R);
     99     }
    100 }
    View Code
  • 相关阅读:
    结对项目——四则运算
    关于结对编程的感想
    《诗词大闯关》调查表与调查结果分析
    我的软件工程课目标
    我的软件工程课目标
    软件工程课程建议
    结对编程(二)
    结对编程——四则运算
    结对编程
    《诗词大闯关》问卷调查心得与体会
  • 原文地址:https://www.cnblogs.com/yijiull/p/7242646.html
Copyright © 2011-2022 走看看