差分约束——HDOJ 1384

HDOJ 1384 Intervals

/*
HDOJ 1384
输入n个区间和n个数字c
区间[a,b]间至少有c个数字
s[i]表示从0到i之间共有多少个整数 
约束条件
s[b]-s[a] >= c
0 <= s[i+1]-s[i] <= 1
要求同时满足这些区间要求的最少的元素个数
求下界,用最长路
*/

#include <iostream>
#include <queue>
using namespace std;

#define MAXN 50010
#define INF 5005000

int head[MAXN];

struct Edge
{
	int e;
	int w;
	int next;
}edge[151000];

bool in_queue[MAXN];
int dis[MAXN];
int n,edgesum;
int star,end;

void Add_edge(int u,int v,int w)
{
	edge[edgesum].e=v;
	edge[edgesum].w=w;
	edge[edgesum].next=head[u];
	head[u]=edgesum++;
}

int SPFA()
{
	for(int i=star;i<=end;i++)
	{
		dis[i]= -INF;
		in_queue[i]=0;
	}
	queue <int> qu;
	in_queue[star]=1;
	dis[star]=0;
	qu.push(star);

	while(!qu.empty())
	{
		int u=qu.front();
		qu.pop();
		in_queue[u]=0;

		for(int i=head[u];i != -1;i=edge[i].next)
		{
			int v=edge[i].e;
			if(dis[v] < dis[u]+edge[i].w)
			{
				dis[v]=dis[u]+edge[i].w;
				if(!in_queue[v])
				{
					qu.push(v);
					in_queue[v]=1;
				}
			}
		}
	}
	return dis[end];
}

int main()
{
	int a,b,c,i;
	while(cin>>n)
	{
		edgesum=1;
		for(i=0;i<MAXN;i++)
			head[i] = -1;
		star=INF;
		end=-INF;
		for(i=0;i<n;i++)
		{
			cin>>a>>b>>c;
			Add_edge(a,b+1,c);
			if(star > a)
				star=a;
			if(end < b+1)
				end=b+1;
		}
		for(i=star;i<end;i++)
		{
			Add_edge(i,i+1,0);
			Add_edge(i+1,i,-1);
		}
		cout<<SPFA()<<endl;
	}
	return 0;
}


你可能感兴趣的:(差分约束——HDOJ 1384)