HDU 1384 查分约束

来源:互联网 发布:win7com端口 编辑:程序博客网 时间:2024/04/29 19:17

点击打开链接

题意:给了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;}

0 0