poj1201差分约束模板题

Posted json-five

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1201差分约束模板题相关的知识,希望对你有一定的参考价值。

http://poj.org/problem?id=1201

题意是给你n个区间,每个区间有一个边界[a,b],以及一个整数c

要满足每个区间[a,b]都至少有c个元素

解题方法就是构造差分约束公式

(a-1)-b<=-c

建立一条边从b到a-1,权值为-c

然后还要加上两个条件

(i+1)-i>=0 -> i-(i+1)<=0

(i+1)-i<=1

#include <cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define N 50005
#define M 500009
const int inf=0x3f3f3f3f;
int dis[N],head[N];
queue<int> q;
int tot;
bool vis[N];
struct Edge
{
    int from,to,cost,next;
} edge[M];
void add(int u,int v,int w)
{
    edge[tot].from=u;
    edge[tot].to=v;
    edge[tot].cost=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void spfa(int u)
{
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[u]=0;
    q.push(u);
    vis[u]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for(int i=head[x]; ~i; i=edge[i].next)
        {
            int y=edge[i].to;
            if(dis[x]+edge[i].cost<dis[y])
            {
                dis[y]=dis[x]+edge[i].cost;
                if(!vis[y]) vis[y]=1,q.push(y);
            }
        }
    }
}
void init()
{
    memset(head,-1,sizeof(head));
    tot=0;
}
int main()
{

    int n;
    while(~scanf("%d",&n))
    {
        init();
        int a,b,w;
        int mina=1e9,maxb=-mina;
        for (int i=0; i<n ; i++ )
        {
            scanf("%d%d%d",&a,&b,&w);
            a++;
            b++;
            add(b,a-1,-w);
            mina=min(mina,a);
            maxb=max(maxb,b);
        }
        for (int i=mina-1; i<maxb ; i++ )
        {
            add(i+1,i,0);
            add(i,i+1,1);
        }
        int s=maxb;
        int t=mina-1;

        spfa(s);
        printf("%d",-dis[t]);
    }
    return 0;
}

 

建立i+1 到 i 权值为 0的边

建立i到i+1 权值为1的边

 

以上是关于poj1201差分约束模板题的主要内容,如果未能解决你的问题,请参考以下文章

[poj 1201]Intervals 差分约束

POJ1201 Intervals (差分约束)

POJ 1201 Intervals 差分约束

「POJ1201」Intervals - 差分约束

POJ1201 Intervals差分约束系统

POJ1201 Intervals 差分约束