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的边

原文地址:https://www.cnblogs.com/Json-Five/p/9783621.html

时间: 2024-08-28 17:25:50

poj1201差分约束模板题的相关文章

poj1201——差分约束,spfa

poj1201——差分约束,spfa Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 22553   Accepted: 8530 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of inte

POJ 1364 King --差分约束第一题

题意:求给定的一组不等式是否有解,不等式要么是:SUM(Xi) (a<=i<=b) > k (1) 要么是 SUM(Xi) (a<=i<=b) < k (2) 分析:典型差分约束题,变换,令Ti = SUM(Xj) (0<=j<=i).  则表达式(1)可以看做T(a+b)-T(a-1) > k,也就是T(a-1)-T(a+b) < -k,又因为全是整数,所以T(a-1)-T(a+b) <= -k-1.  同理,(2)看做T(a+b)-T(

poj1201差分约束

#include<stdio.h> #include<iostream> #include<string.h> #include<queue> #include<stack> #include<list> #include<stdlib.h> #include<algorithm> #include<vector> #include<map> #include<set> #i

POJ1201 差分约束

给定ai,bi, ci 表示区间[ai,bi]内至少有ci个点, 要求对于所有给定的ai,bi,ci,  至少多少个点才能满足题目的条件 重做这一题学到的一点是, 可以设变量来表示一些东西,然后才能找出约束的条件,  s[i]表示区间0到i内有多少个点,  那么s[bi] - s[ai-1] >= ci 就是约束的条件 当然了,也有隐藏的条件  1>= s[i] - s[i-1] >=0 可以用最长路来求这一题,最短路当然也是可以的. #include <stdio.h> #

poj1201(差分约束)

题很水...但我被坑惨了 ........ ........... ....... 构成差分约束系统时,1.如果在所有点外添加一个超级源0号点,并使得超级源到所有其他点的距离为0,那么最终求出的0号点到其他所有原始点的最短距离就是本系统的一个可行解,且可行解之间的差距最小.      2.如果初始时不添加超级源,只是将原始点的初始距离设为INF,且令其中一个原始点的初始距离为0,然后求该点到其他所有点的最短距离,那么最短距离的集合就是一个可行解,且该可行解两两之间的差距最大.注意方案2只能在该问

POJ 1716 Interger Intervals 差分约束(入门题)

题意:给出n个区间[a,b] n,a,b<=1e4,要求找到一个最小集合 使得每个区间至少有两个数在集合中.设d[i]为0~i中有多少个元素在集合中,mn,mx分别为左右端点 则对每个i=1..n都要满足 d[b[i]]-d[a[i]-1]>=2 保证等式有意义,d[i+1]<=d[i]+1 , d[i]<=d[i+1]全部化为小于号 d[a[i]-1]-d[b[i]]<=-2 若答案为ans 则d[mx]-d[mn-1]>=ans 把mx当作源点,求出到mn-1的最短

差分约束入门题ZOJ2770&amp;&amp;AOJ517

http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=517 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2770 重点是建图,建完图,跑一边最短路,求出最短距离就行了 具体建图见图论算法书P201 ZOJ2770 #include <cstdio> #include <cstring> #include <cmath> #include <algorith

差分约束 刷题记录

把问题转化成一堆不等式,然后用最短路求解 POJ3169 Layout 最后要求1和n之间最大dis是多少  ->  转化为得到一堆  d[n] - d[1] <= xi  然后求xi的最小值 对于给出的是d[u] - d[v] >= xi  同乘-1转化为 d[v] - d[u] <= -xi 即可 然后用spfa求 1到n的最短路 若有负环则无解,若求得的最短路为inf则说明1,n间距离可随便大 代码: 1 #include <cstdio> 2 #include

poj 1275 Cashier Employment 差分约束

差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键. 代码: //poj 1275 //sep9 #include <iostream> #include <queue> using namespace std; const int maxM=10024; const int maxN=32; struct Edge { int v,w,nxt; }edge[maxM]; int t[maxN],c[maxN],head[maxN],vis[maxN],inq