POJ.1752.Advertisement(差分约束 最长路SPFA)

题目链接

\(Description\)

有n个人在一条直线上跑步,每个人的起点 \(Si\)、终点 \(Ei\) 已知;每个点可以放一个广告牌,一个人i能看到的广告牌数量为 \(Ei-Si+1\)。
要求使每个人看到的广告牌数量不小于 \(k\) (若 \(Ei-Si+1<k\) 则应看到 \(Ei-Si+1\))。输出最少需要多少广告牌及方案。

(这翻译2333)

\(Solution\)

设 \(Sum_i\) 表示在 \([1,i]\) 广告牌总数,那么由题意有 \(Sum_{Ei}-Sum_{Si-1}>=k\),这是对于 \(Ei-Si+1>=k\) 的
设 \(C=Ei-Si+1\),若C<k,则 \(Sum_{Ei}-Sum_{Si-1}=C\),拆成两个式子
同时每个位置的限制 \(0<=Sum_i-Sum{i-1}<=1\)
以 \(Sum_i\) 为点建边,求 \(Sum_0\) -> \(Sum_n\) 的最长路即为最少需要数量
输出方案: 若i处建了广告牌,则有 \(dis_i-dis_{i-1}=1\)

注意,Dijkstra不能用来求最长路

//1240K 735MS
#include <queue>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define mp std::make_pair
#define pr std::pair<int,int>
const int N=10005,M=60005,INF=0x3f3f3f3f;

int n,K,Enum,H[N<<1],nxt[M],to[M],val[M],dis[N<<1];
bool vis[N<<1];
//std::priority_queue<pr> q;
std::queue<int> que;

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
inline void AddEdge(int u,int v,int w){
    to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, val[Enum]=w;
}
//int Dijkstra(int mn,int mx)
//{
//  for(int i=mn+1; i<=mx; ++i) dis[i]=-INF;
//  q.push(mp(0,mn));
//  while(!q.empty())
//  {
//      int x=q.top().second;q.pop();
//      if(vis[x]) continue;
//      vis[x]=1;
//      for(int i=H[x]; i; i=nxt[i])
//          if(dis[to[i]]<dis[x]+val[i])
//          {
//              dis[to[i]]=dis[x]+val[i];
//              if(!vis[to[i]]) q.push(mp(dis[to[i]],to[i]));
//          }
//  }
//  return dis[mx];
//}
int SPFA(int mn,int mx)
{
    for(int i=mn+1; i<=mx; ++i) dis[i]=-INF;
    que.push(mn);
    while(!que.empty())
    {
        int x=que.front();que.pop();
        vis[x]=0;
        for(int i=H[x]; i; i=nxt[i])
            if(dis[to[i]]<dis[x]+val[i])
            {
                dis[to[i]]=dis[x]+val[i];
                if(!vis[to[i]]) que.push(to[i]),vis[to[i]]=1;
            }
    }
    return dis[mx];
}

int main()
{
    K=read(),n=read();
    int mx=0,mn=N<<1;
    for(int st,ed,t,i=1; i<=n; ++i)
    {
        st=read()+N, ed=read()+N;
        if(st>ed) std::swap(st,ed);
        mn=std::min(mn,--st), mx=std::max(mx,ed);
        if((t=ed-st)<K) AddEdge(st,ed,t),AddEdge(ed,st,-t);
        else AddEdge(st,ed,K);
    }
    mn-=2;
    for(int i=mn; i<=mx; ++i) AddEdge(i-1,i,0),AddEdge(i,i-1,-1);
    printf("%d\n",SPFA(mn,mx));
    for(int i=mn; i<=mx; ++i)
        if(dis[i]==dis[i-1]+1) printf("%d\n",i-N);
    return 0;
}

原文地址:https://www.cnblogs.com/SovietPower/p/8496675.html

时间: 2024-11-02 14:29:14

POJ.1752.Advertisement(差分约束 最长路SPFA)的相关文章

HDU.1529.Cashier Employment(差分约束 最长路SPFA)

题目链接 \(Description\) 给定一天24h 每小时需要的员工数量Ri,有n个员工,已知每个员工开始工作的时间ti(ti∈[0,23]),每个员工会连续工作8h. 问能否满足一天的需求.若能,输出最少需要多少员工. \(Solution\) 参考. 既然给的是开始工作时间,那么就先根据开始时间做 设Ai表示在i时开始工作的人数(未知),Bi表示i时可工作人数的上限(已知) 那么有:(注意可以跨天) A[i-7]+A[i-6]+...+A[i-1]+A[i] >= R[i] (7 <

POJ 3169 Layout (差分约束+SPFA)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6832   Accepted: 3292 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

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(

POJ 1364 King 差分约束 找负环

嘛,虽然是一道水题+模板题,不过还是学到了很多东西的,记录一下. 首先题目给出的不等式是小于,但是差分约束系统只能处理小于等于的情况,所以要转化成小于等于的进行处理.对于整数处理方法非常简单= = 然后是找负环的情况,其实不需要考虑图连不连通,只要一开始就把所有的点的d置成0,然后都push进队列里面就好了. PS:这种方法同样可以用在处理多源点最短路问题上. #include <cstdio> #include <cstring> #include <cmath> #

POJ 1201 Intervals 差分约束

http://poj.org/problem?id=1201 TLE了很久,因为用了cin..... 思路和其他差分约束差不多,http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 如果区间[a, b]中至少有c个元素,如果用上面的博客,那么说明xa - xb >= c,但是注意这里是闭区间,xa - xb是不包括b这个点的, 就比如用了[a, b]有c个元素,[b, d]有x个,那么ans = c + x - 1个,

POJ 3169 Layout (差分约束)

题意:给定一些母牛,要求一个排列,有的母牛距离不能超过w,有的距离不能小于w,问你第一个和第n个最远距离是多少. 析:以前只是听说过个算法,从来没用过,差分约束. 对于第 i 个母牛和第 i+1 个,D[i] - D[i+1] <= 0,  D[j] -D[i ]<= k, D[i] - D[j] <= - k,那么这个题就可以用差分约束来求这个不等式组了. 1.对于差分不等式,a - b <= c ,建一条 b 到 a 的权值为 c 的边,求的是最短路,得到的是最大值(本题求的就

poj 3169 Layout (差分约束+Bellman )

题目链接:http://poj.org/problem?id=3169 题意:输入N, ML, MD, N默示有N个牛按1-N排成一排,ML,默示有ML行,每行输入A, B, D默示A牛和B牛最远间隔为D, MD默示有MD行,每行输入A,B,D默示A牛和B来间隔为D,求满足所有前提的1-N的最大间隔. 比较简单的差分约束,这个周周赛的A题 #include <iostream> #include <cstdlib> #include <cstdio> #include

POJ 3159 Candies 差分约束

链接:http://poj.org/problem?id=3159 Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 24852   Accepted: 6737 Description During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher brought the

poj 1364 King(差分约束)(中等)

King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11028   Accepted: 4040 Description Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound kin