题目链接:poj 1201
给定每个范围内取数的最小个数,求整个数组最少取多少个数
差分约束系统,将条件转化为边,最终求的就是最长路的结果
/******************************************************
* File Name: 1201.cpp
* Author: kojimai
* Creater Time:2014年08月19日 星期二 23时27分43秒
******************************************************/
/*
*给定你一些条件,表示从a~b区间至少取c个数,问整个数组至少取多少个数能使得所有条件都满足
*差分约束系统:s[i]表示从0到i为止至少出现的个数,s[b]-s[a-1]>=c 0<=s[i]-s[i-1]<=1
**dist[b+1]>=dist[a]+c dist[i+1]>=dist[i]+0 dist[i]>=dist[i+1]-1
***s[b+1]-s[a]>=k1 s[c+1]-s[b+1]>=k2 s[c+1]-s[a]>=k3 s[c+1]-s[a]>=max(k1+k2,k3)
**最终结果转化为求从起点到终点的最长路即可
*/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define FFF 50005
#define INF 233333333
int e;
struct edge
{
int v;
int w;
int next;
}edge[3*FFF];
int first[FFF],dis[FFF],vis[FFF];
int n,Min,Max;
void addedge(int u,int v,int w)
{
edge[e].v=v;
edge[e].w=w;
edge[e].next=first[u];
first[u]=e++;
}
void spfa()
{
for(int i=Min;i<=Max;i++)
dis[i]=-INF;
dis[Min]=0;
queue<int> p;
p.push(Min);
vis[Min]=true;
while(!p.empty())
{
int x=p.front();p.pop();
vis[x]=false;
for(int k=first[x];~k;k=edge[k].next)
{
if(dis[edge[k].v]<dis[x]+edge[k].w)
{
dis[edge[k].v]=dis[x]+edge[k].w;
if(!vis[edge[k].v])
{
p.push(edge[k].v);
vis[edge[k].v]=true;
}
}
}
}
return ;
}
int main()
{
while(~scanf("%d",&n))
{
int u,v,w;
e=0;
Min=INF;Max=-INF;
memset(first,-1,sizeof(first));
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v+1,w);
Min=min(Min,u);
Max=max(Max,v+1);
}
for(int i=Min;i<Max;i++)
{
addedge(i,i+1,0);
addedge(i+1,i,-1);
}
spfa();
printf("%d\n",dis[Max]);
}
return 0;
}