poj1201 intervals

给出数轴上的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-11111111
using 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]);//结果在最短路中的意义
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值