POJ1201 区间

题目大意:

给定n个整数区间[ai,bi]和n个整数ci,求一个最小集合Z,满足|Z∩[ai,bi]|>=ci(Z里边在闭区间[ai,bi]的个数不小于ci)。

多组数据:

n(1<=n<=50000)区间的个数

n行:

ai bi ci(0<=ai<=bi<=50000,1<=ci<=bi-ai+1)

_____________________________________________________

这是一道查分约束题目。

Si为0-i中包含在Z中的个数,固有:

Si-Si-1<=1

Si-Si-1>=0

Sbi-Sai-1>=ci

依照上面不等式,变形并建边。

求的Smax-S0>=x,变形为S0-Smax<=-x,所以求max到0的最短路,就是答案的相反数。

_____________________________________________________

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<queue>
 7 using namespace std;
 8 int n,maxd;
 9 struct edge
10 {
11     int u,v,w,next;
12 }e[150010];
13 int head[50010],js=0;
14 int dis[50010];
15 bool inq[50010];
16 int inqt[50010];
17 queue<int>q;
18 void init()
19 {
20     js=0;
21     maxd=0;
22     memset(head,0,sizeof(head));
23 }
24 void addage(int u,int v,int w)
25 {
26     e[++js].u=u;e[js].v=v;e[js].w=w;
27     e[js].next=head[u];head[u]=js;
28 }
29 bool spfa()
30 {
31     memset(inq,0,sizeof(inq));
32     memset(dis,0x7f,sizeof(dis));
33     memset(inqt,0,sizeof(inqt));
34     q.push(maxd+1);
35     inq[maxd+1]=1;
36     inqt[maxd+1]=1;
37     dis[maxd+1]=0;
38     while(!q.empty())
39     {
40         int u=q.front();
41         q.pop();
42         inq[u]=0;
43         for(int i=head[u];i;i=e[i].next)
44         {
45             int v=e[i].v;
46             if(dis[v]>dis[u]+e[i].w)
47             {
48                 dis[v]=dis[u]+e[i].w;
49                 if(!inq[v])
50                 {
51                     inq[v]=1;
52                     inqt[v]++;
53                     q.push(v);
54                     if(inqt[v]>50000)return 0;
55                 }
56             }
57         }
58     }
59     return 1;
60 }
61 int main()
62 {
63     while(scanf("%d",&n)==1)
64     {
65         init();
66         for(int a,b,c,i=1;i<=n;i++)
67         {
68             scanf("%d%d%d",&a,&b,&c);
69             if(b>maxd)maxd=b;
70             addage(b+1,a,-c);
71         }
72         
73         for(int i=1;i<=maxd+1;i++)
74         {
75             addage(i-1,i,1);
76             addage(i,i-1,0);
77         }
78         if(spfa())printf("%d\n",-dis[0]);
79     }
80     return 0;
81 }
View Code
原文地址:https://www.cnblogs.com/gryzy/p/6212196.html