[POJ1716]Integer Intervals(差分约束系统)

来源:互联网 发布:手机电话轰炸机软件 编辑:程序博客网 时间:2024/05/19 23:58

题目描述

传送门

题解

dis[i]表示区间[0,i]所选数的个数。
由于求最小值,想到用最长路来解。
于是可以画出来一堆式子,满足disi>=disj+k
同时不要忘了题目中的隐含条件,即disi>=disi+11disi+1>=disi
由于上一个条件,保证图连通,所以不必要连超级源点。
根据所化出的式子连边,用spfa求解即可。
听说这道题也可以贪心。

代码

#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int max_N=1e4+5;const int max_m=max_N*2;const int max_e=max_m*2;const int INF=1e9;int n,N,M,l,r,u,t,ans;int tot,point[max_N],next[max_e],v[max_e],c[max_e];int dis[max_N];bool vis[max_N];queue <int> q;inline void addedge(int x,int y,int z){    ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;}inline void spfa(){    memset(dis,128,sizeof(dis));    memset(vis,0,sizeof(vis));    dis[0]=0;    vis[0]=true;    while (!q.empty()) q.pop();    q.push(0);    while (!q.empty()){        int now=q.front(); q.pop();        vis[now]=false;        for (int i=point[now];i;i=next[i])          if (dis[v[i]]<dis[now]+c[i]){            dis[v[i]]=dis[now]+c[i];            if (!vis[v[i]]){                vis[v[i]]=true;                q.push(v[i]);            }          }    }}int main(){    scanf("%d",&n);    N=0; M=INF;    for (int i=1;i<=n;++i){        scanf("%d%d",&l,&r);        u=l;        t=r+1;        N=max(N,t);        addedge(u,t,2);    }    for (int i=0;i<N;++i){        addedge(i+1,i,-1);        addedge(i,i+1,0);    }    spfa();    ans=dis[N];    printf("%d\n",ans);}

总结

①线性规划注意挖掘题目中的隐含条件(lcomyn互测题)
②差分约束也可转化为最长路来解。

0 0