Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 30103 | Accepted: 11643 |
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
Source
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=500100;
const int MAXM=MAXN*5;
#define INF 0x3f3f3f3f
struct Node
{
int to;
int w;
};
vector<Node> G[MAXM];
bool vis[MAXN];
int visitcount[MAXN];
queue <int> q;
int dis[MAXN];
void init(int n)
{
int i;
for(i=0;i<=n;i++)
G[i].clear();
}
void addedge(int u,int v,int w)
{
Node t={v,w};
G[u].push_back(t);
}
bool spfa(int s,int n)//单源最短路(s为起点,n为节点总数)
{
int u;
for(int i=s;i<=s+n-1;i++)
dis[i]=INF;
memset(vis,0,sizeof(vis));
memset(visitcount,0,sizeof(visitcount));
while(!q.empty())
q.pop();
q.push(s);
vis[s]=true;
dis[s]=0;
while (!q.empty())
{
u=q.front();
q.pop();
vis[u]=false;
if(visitcount[u]++>n)
return true; //return true说明有负权圈
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i].to;
int w=G[u][i].w;
if (dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if (!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
return false;
}
int main()
{
int n;
int i;
int u,v,w;
scanf("%d",&n);
int minn=INF,maxn=0;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&u,&v,&w);
u+=1;
v+=1;
minn=min(minn,u);
maxn=max(maxn,v);
addedge(u-1,v,-w);
}
for(i=minn;i<=maxn;i++)
{
addedge(i-1,i,0);
addedge(i,i-1,-1*(-1)); //因为添的都是负权边
}
if(!spfa(minn-1,maxn-minn+2))
{
printf("%d\n",-dis[maxn]);
}
return 0;
}