码迷,mamicode.com
首页 > 其他好文 > 详细

『一本通』差分约束系统

时间:2019-02-16 15:19:23      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:name   code   queue   16px   bool   pop   表示   memset   mem   

Intervals

设$s[k]$表示$0$~$k$之间最少选出多少个整数。

由题得$s[b_i]-s[a_i-1]\ge c_i$,$0\le s[k+1]-s[k] \le 1$ 。

根据关系式连边,$SPFA$ 跑一遍 最长路 即可。

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
int n,cnt,Min,Max,fro[N],dis[N];
bool vis[N];
struct edge{int to,w,nxt;}e[N<<2];
queue<int> q;
void add(int x,int y,int z) {
    e[++cnt].to=y,e[cnt].w=z,e[cnt].nxt=fro[x]; fro[x]=cnt;
}

int SPFA() {
    memset(dis,-0x3f,sizeof(dis));
    dis[Min]=0,vis[Min]=1;
    q.push(Min);
    while(!q.empty()) {
        int u=q.front();
        q.pop(),vis[u]=0;
        for(int i=fro[u];i;i=e[i].nxt) {
            int v=e[i].to;
            if(dis[v]<dis[u]+e[i].w) {
                dis[v]=dis[u]+e[i].w;
                if(!vis[v]) vis[v]=1,q.push(v);
            }
        }
    }
    return dis[Max];
}

int main() {
    scanf("%d",&n);
    int a,b,c;
    Min=N+1,Max=-1;
    for(int i=1;i<=n;i++) {
        scanf("%d%d%d",&a,&b,&c);
        add(a-1,b,c);
        Min=min(Min,a-1),Max=max(Max,b);
    }
    for(int i=Min;i<=Max;i++) 
     add(i,i+1,0),add(i+1,i,-1);
    printf("%d",SPFA());
}

 

『一本通』差分约束系统

标签:name   code   queue   16px   bool   pop   表示   memset   mem   

原文地址:https://www.cnblogs.com/qq8260573/p/10387599.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!