题意:给了n个区间,要求每个区间至少有C个数字出现,问满足的最小的数字个数
思路:用Si代表0到i的区间内的数字个数,然后可以写出查分约束方程,对于一个区间则Sa-S(b-1)>=C的,然后隐含的一个条件就是Si-S(i-1)>=0且<=1的,然后泡个最长路就行,对于查分约束系统求最大值是<=的形式,而求最小值则是>=的形式
#include <queue> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=50010; int dis[maxn],head[maxn],n,k; bool vis[maxn]; struct edge{ int to,w,next; }E[maxn*10]; void add_edge(int u,int v,int w){ E[k].to=v;E[k].w=w;E[k].next=head[u];head[u]=k++; } void spfa(int S){ queue<int>que; memset(dis,-inf,sizeof(dis)); memset(vis,0,sizeof(vis)); que.push(S);dis[S]=0; while(!que.empty()){ int t=que.front();que.pop(); vis[t]=0; for(int i=head[t];i!=-1;i=E[i].next){ if(dis[t]+E[i].w>dis[E[i].to]){ dis[E[i].to]=dis[t]+E[i].w; if(!vis[E[i].to]){ vis[E[i].to]=1; que.push(E[i].to); } } } } } int main(){ int u,v,c; while(scanf("%d",&n)!=-1){ k=0; memset(head,-1,sizeof(head)); int S=inf,T=-inf; for(int i=0;i<n;i++){ scanf("%d%d%d",&u,&v,&c); S=min(S,u-1);T=max(T,v); add_edge(u-1,v,c); } for(int i=S+1;i<=T;i++){ add_edge(i-1,i,0); add_edge(i,i-1,-1); } spfa(S); printf("%d\n",dis[T]); } return 0; }
原文:http://blog.csdn.net/dan__ge/article/details/51892441