您的位置:首页 > 其它

poj1201 intervals

2016-07-27 14:46 495 查看
给出数轴上的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
-dis[start]);//结果在最短路中的意义
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: