• 【学习】差分约束


    今天%你赛考了差分约束相关,于是发现又有忘了的东西,复习

    0x00 差分约束

    差分约束是求解N元一次特殊不等式组的一种方法。差分约束系统包含$N$个变量和$M$个约束条件,每个约束条件都是一个关于其中两个变量的一个一次不等式

    ,每个不等式形如$x[i]-x[j]≤a[k]$,$x[i],x[j]$为变量,$a[k]$为常数。

    引理:若${Xi}$为差分约束系统的一组解,$∆$为任意常数,那么${Xi+∆}$也是一组解。

    0x10 最短路

    差分约束系统中的每个不等式都与最短路中的三角形不等式$dis[v]≤dis[u]+e(u,v)$,即$dis[v]-dis[u]≤e(u,v)$形似。

    所以我们把每个变量$x_i$看做有向图中的一个点i,对于每个不等式$x[i]-x[j]≤a[k]$,即$x[i]≤x[j]+a[k]$,可看做从$j$向$i$连一条有向边,边权为$a[k]$。

    另设源点$S$,由$S$向所有点建边权为$a$的边,求完最短路后的$dis[i]$即为$X[i]$的一组解。

    如果有负环,说明无解。

    如果想求最小值,将不等式*=-1,则≤变为≥,用最长路解决即可,如果有正环则无解。

    0x11 负环问题

    如何判断是否出现负环?

    ①记录每个点的入队次数,若某个点入队超过n次说明有负环。

    ②记录更新到每个点的最短路长度,如果dis[x]+e(x,y)更新了y,那么len[y]=len[x]+1,若长度超过n说明有负环。

    被学长推荐第二种

    0x20 例题

    poj 3169

    Luogu P1993 小k的农场

    裸的板板

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define ll long long
     5 const int inf=1e9+7;
     6 const int maxn=1e5+10;
     7 inline int read(){
     8     int x=0,f=1;
     9     char c=getchar();
    10     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    11     while(c>='0'&&c<='9'){x=(x*10)+c-'0';c=getchar();}
    12     return x*f;
    13 }
    14 struct edge{
    15     int to,nxt,w;
    16 }e[maxn*2];
    17 int head[maxn],cnt,vis[maxn],dis[maxn];
    18 inline void add(int from,int to,int w){
    19     e[++cnt].to=to;e[cnt].w=w;
    20     e[cnt].nxt=head[from];head[from]=cnt;
    21 }
    22 bool spfa(int x){
    23     vis[x]=1;
    24     for(int i=head[x];i;i=e[i].nxt){
    25         int y=e[i].to;
    26         if(dis[y]<dis[x]+e[i].w){
    27             dis[y]=dis[x]+e[i].w;
    28             if(vis[y])return 0;
    29             if(!spfa(y))return 0;
    30         }
    31     }
    32     vis[x]=0;
    33     return 1;
    34 }
    35 int n,m;
    36 int main(){
    37     n=read();m=read();
    38     for(int i=1;i<=m;i++){
    39         int x,a,b,c;
    40         x=read();
    41         if(x==1){
    42             a=read();b=read();c=read();
    43             add(b,a,c);
    44         }
    45         if(x==2){
    46             a=read();b=read();c=read();
    47             add(a,b,-c);
    48         }
    49         if(x==3){
    50             a=read();b=read();
    51             add(a,b,0);add(b,a,0);
    52         }
    53     }
    54     for(int i=1;i<=n;i++){
    55         add(0,i,0);
    56         dis[i]=-inf;
    57     }
    58     if(!spfa(0))puts("No");
    59     else puts("Yes");
    60     return 0;
    61 }
    62 }
    63 signed main(){
    64   gengyf::main();
    65   return 0;
    66 }
    View Code

    Luogu P3275 [SCOI 2011]糖果

    题解  (再次不要脸行为)

  • 相关阅读:
    Struts2框架(二)
    Struts2框架(一)
    jsp定义全局的错误处理
    BeanUtils的使用、Java中的路径问题
    IntelliJ IDEA 14.1.4(Window)快捷键
    Log4J日志组件
    注解
    反射
    泛型
    AndroidStudio开发工具快捷键(转)
  • 原文地址:https://www.cnblogs.com/gengyf/p/11620331.html
Copyright © 2020-2023  润新知