HDU3870- intervals(差分约束)
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
这是一个差分约束的基础题;
求最长路即可;
AC代码为:
//scanf,printf过了。cin cout T了Orz #include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=1e5+10; int n,tot,S,T,u,v,w; int dis[maxn],first[maxn],vis[maxn]; struct Node{ int v,w,net; } edge[maxn*10]; void addedge(int u,int v,int w) { edge[tot].v=v; edge[tot].w=w; edge[tot].net=first[u]; first[u]=tot++; } void SPFA(int s) { queue<int> q; memset(dis,-INF,sizeof dis); memset(vis,0,sizeof vis); q.push(s); dis[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=first[u];~i;i=edge[i].net) { if(dis[edge[i].v]<dis[u]+edge[i].w) { dis[edge[i].v]=dis[u]+edge[i].w; if(!vis[edge[i].v]) { vis[edge[i].v]=1; q.push(edge[i].v); } } } } } int main() { while(~scanf("%d",&n)) { tot=1, S=INF,T=-INF; memset(first,-1,sizeof first); for(int i=1;i<=n;i++) { scanf("%d%d%d",&u,&v,&w); S=min(S,u-1),T=max(T,v); addedge(u-1,v,w); } for(int i=S;i<T;i++) { addedge(i,i+1,0); addedge(i+1,i,-1); } SPFA(S); printf("%d\n",dis[T]); } return 0; }