poj1201 intervals

来源:互联网 发布:java布局方式 编辑:程序博客网 时间:2024/06/08 18:45

给出数轴上的n个区间[ai,bi],现在要在数轴上选取元素,构成一个元素集合V,要求区间[ai,bi]和集合V的交集至少有ci不同的元素,求集合V最少要有的元素个数。
约束关系分析:

明显有条件dis[bi]-dis[ai]>=ci(dis[bi]>=dis[ai]+ci,类比dis[v]>=dis[u]+w,所以bi为该边终点,ai为该边起点),要求问题的结果可用dis表示为dis[max]-dis[min],再类比一条边的起点和终点,得max为终点,min为起点。(最长路)

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<climits>#include<queue>#include<vector>#include<set>#include<stack>#include<map>#include<list>#define mem(a) memset(a,0,sizeof(a))#define maxn 51000#define MAX INT_MAX-11111111using namespace std;struct node{int v,w;int next;node():v(-1),w(-1),next(-1){}}head[maxn],Pt[maxm];bool vis[maxn];int dis[maxn], top=0;void build(int u,int v,int w){    int p=top++;    Pt[p].v=v;    Pt[p].w=w;    Pt[p].next=head[u].next;    head[u].next=p;}void spfa(int start,int n){    mem(vis);    for(int i=0;i<=n;++i)        dis[i]=-(MAX);//因为有负权边,初始化为零不能用负权边松弛dis[i]==0的边    dis[start]=0;stack<int>que;//也可以是队列    que.push(start);    vis[start]=true;    while(!que.empty())    {        int u=que.top(),v,w;        que.pop();        vis[u]=false;        for(int p=head[u].next;p!=-1;p=Pt[p].next)        {            v=Pt[p].v;            w=Pt[p].w;            if(dis[v]<dis[u]+w)            {                dis[v]=dis[u]+w;                if(!vis[v]) {                    que.push(v);                    vis[v]=true;                }            }        }    }}int main(){    int m ,n=0;    scanf("%d",&m);    int i,u,v,w,start=MAX;    for(i=0;i<m;++i)    {        scanf("%d%d%d",&u,&v,&w);        build(u,v+1,w);        n=max(n,v+1);        start=min(start,u);    }    for(i=start;i<=n;++i)//隐藏条件    {        build(i,i+1,0);        build(i+1,i,-1);    }    spfa(start,n);//0~n  n+1个    printf("%d\n",dis[n]-dis[start]);//结果在最短路中的意义}


0 0