【HDOJ1384】【差分约束+SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1384

Intervals

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4638    Accepted Submission(s): 1765


Problem Description
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:

> reads the number of intervals, their endpoints and integers c1, ..., cn from the standard input,

> computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i = 1, 2, ..., n,

> writes the answer to the standard output
 
Input
The first line of the input contains an integer n (1 <= n <= 50 000) - the number of intervals. The following n lines describe the intervals. The i+1-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <= ai <= bi <= 50 000 and 1 <= ci <= bi - ai + 1.

Process to the end of file.

Output
The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i = 1, 2, ..., n.
 
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
 
Sample Output
6

题目大意:给若干个区间,并且每个区间给定一个数C,表示集合S至少含有这个区间内C个整数,求满足要求的S的最小元素数

题目分析:典型的差分约束题目,即能根据题设条件列出若干不等式,并且所求问题中含有最小【或最大,最多,最少】字眼。都可以列出不等式,然后转化为最短路或者最长路。

     本题要求区间【LI,RI】内含有CI个整数,即可令S【I】表示最终集合S在【0,I】区间内含有的整数,则本题要求即可化为S【RI】-S【LI-1】>= CI【条件不等式一】

     又因为S【I】-S【I-1】>= 0 && S【I】-S【I-1】<= 1【条件不等式二、三】

       题目所求最小元素数ANS  即S【Rmax】-s【Lmin-1】>= ANS  【所求不等式】

      由所求不等式确定所求最长路还是最短路,从而据此再根据条件不等式可以建图,SPFA跑一遍即可。

【PS:边的结构体数组一定要开大一点,不然会TLE到怀疑人生...】

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<queue>
 6 using namespace std;
 7 const int INF=100005;
 8 struct edge{
 9     int to;
10     int len;
11     int next;
12 }EDGE[200005];
13 queue<int>pq;
14 int edge_cnt=0,dist[50006],stk[50006],head[50006],n; 
15 void add(int x,int y,int z)
16 {
17     EDGE[edge_cnt].to=y;
18     EDGE[edge_cnt].next=head[x];
19     EDGE[edge_cnt].len=z;
20     head[x]=edge_cnt++;
21 }
22 void spfa()
23 {
24     while(!pq.empty())
25     {
26         int qwq=pq.front();pq.pop();
27         stk[qwq]=0;
28         for(int i = head[qwq] ; i != -1 ; i = EDGE[i].next)
29         {
30             int v=EDGE[i].to;
31             if(dist[v]<dist[qwq]+EDGE[i].len)
32             {
33                 dist[v]=dist[qwq]+EDGE[i].len;
34                 if(!stk[v]){
35                 stk[v]=1;
36                 pq.push(v);
37             }            
38             }
39         }
40     }
41 }
42 int main()
43 {
44     while(scanf("%d",&n)==1)
45     {
46         edge_cnt=0;
47         int mmin=500000;
48         int mmax=-1;
49         memset(dist,-1,sizeof(dist));
50         memset(stk,0,sizeof(stk));
51         memset(head,-1,sizeof(head));
52         while(!pq.empty())pq.pop();
53         while(n--)
54         {
55             int a,b,c;
56             scanf("%d%d%d",&a,&b,&c);
57             if(a)
58             add(a-1,b,c);
59             else
60             {
61                 add(50005,b,c);
62             }
63             mmax=max(b,mmax);
64             mmin=min(a,mmin);
65         }
66         if(mmin==0)
67         {
68             dist[50005]=0;
69             add(50005,0,0);
70             add(0,50005,-1);
71             mmin=1;
72             stk[50005]=1;
73             pq.push(50005);
74         }
75         else
76         {
77             stk[mmin-1]=1;
78             pq.push(mmin-1);
79             dist[mmin-1]=0;
80         }
81         for(int i = mmin-1;i<mmax;i++)
82         {
83             add(i+1,i,-1);    
84             add(i,i+1,0);
85         }
86         spfa();
87     printf("%d\n",dist[mmax]);
88     }
89     return 0;
90 }

 

转载于:https://www.cnblogs.com/MekakuCityActor/p/9018181.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值