hdu 三部曲1 Intervals 差分约束问题 spfa算法

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 end points 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 <= 50000) -- 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 <= 50000 and 1 <= ci <= bi - ai+1.
 
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
***************************************************************************************************************************
差分约束n个数和m个约束条件,求满足条件的一组数据,其中xi-xj<=bs正好满足spfa中的三角式子,于是该题就变成了图论题即求最短路的问题,找范围(找到一个源点)建图时要建全。
***************************************************************************************************************************
 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cctype>
 6 #include<queue>
 7 #include<stack>
 8 using namespace std;
 9 const int inf=999999999;
10 const int maxn=50050;
11 int dis[maxn],vis[maxn],n;
12 int aa,bb;
13 struct node
14  {
15      int v;
16      int value;
17  }tmp;
18 vector<node>map[maxn];
19 void spfa()//求最长路
20 {
21     memset(vis,0,sizeof(vis));
22     queue<int>Q;
23     for(int it=aa;it<=bb;it++)
24      dis[it]=-inf;
25     while(!Q.empty())
26     Q.pop();
27     Q.push(aa);
28     vis[aa]=1;
29     dis[aa]=0;
30     while(!Q.empty())
31     {
32         int gs=Q.front();
33           Q.pop();
34           vis[gs]=0;
35           int sn=map[gs].size();
36         for(int it=0;it<sn;it++)
37         {
38               if((dis[map[gs][it].v]<dis[gs]+map[gs][it].value))
39               {
40                   dis[map[gs][it].v]=dis[gs]+map[gs][it].value;
41                   if(vis[map[gs][it].v]==0)
42                   {
43                       Q.push(map[gs][it].v);
44                       vis[map[gs][it].v]=1;
45                   }
46               }
47         }
48     }
49 }
50 int main()
51 {
52     scanf("%d",&n);
53     int st,en,w;
54     aa=maxn;
55     bb=-1;
56     //满足不等式s[en]-s[st-1]>=w;
57     for(int i=1;i<=n;i++)
58     {
59         scanf("%d %d %d",&st,&en,&w);
60         if(st<aa)aa=st;
61         if((en+1)>bb)bb=en+1;
62         tmp.value=w;
63         tmp.v=en+1;
64         map[st].push_back(tmp);
65 
66     }
67     //0<=s[i+1]-s[i]<=1
68     for(int it=aa;it<=bb;it++)
69     {
70         //添加0边和-1边
71         tmp.value=0;
72         tmp.v=it+1;
73         map[it].push_back(tmp);
74         tmp.value=-1;
75         tmp.v=it;
76         map[it+1].push_back(tmp);
77     }
78     spfa();
79     printf("%d\n",dis[bb]);//最大范围的最长边即为结果
80     return 0;
81 }
View Code

坚持!多刷题!

转载于:https://www.cnblogs.com/sdau--codeants/p/3352113.html

猜你喜欢

转载自blog.csdn.net/weixin_34417635/article/details/93432931