poj2374 Fence Obstacle Course(线段树+建图spfa)
来源:互联网 发布:北师大网络教育登录 编辑:程序博客网 时间:2024/06/05 20:39
从上往下看,每条栅栏只有左右端点有意义,而且从每个点出发只会在一条栅栏处停下,所以每个点最多连两条边。我们可以用线段树维护这个连边操作。(每个点只有第一次被覆盖时连边,然后每次把两个端点加进去)然后从s点再连一下,最后剩的都再和终点连一下,然后跑最短路即可。
#include <cstdio>#include <cstring>#include <algorithm>#include <deque>using namespace std;#define inf 0x3f3f3f3f#define ll long long#define N 50010#define M 200010#define treen 200001inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}int n,s,num=0,h[N<<1],id1,id2,tot=1;ll d[N<<1];bool inq[N<<1];struct node{ int x,id;}tree[M<<2];struct dat{ int x,y;}a[N];struct edge{ int to,next,val;}data[N<<2];inline void add(int x,int y,int val){ data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val;}void build(int p,int l,int r){ if(l==r) return; int mid=l+r>>1; build(p<<1,l,mid);build(p<<1|1,mid+1,r);}void solve(int p,int l,int r,int x,int y){ if(tree[p].x==0) return; if(l==r){ if(id2==id1) add(tree[p].id,id1,abs(l-100001)); else add(tree[p].id,id1,l-x),add(tree[p].id,id2,y-l); tree[p].x=0;return; } int mid=l+r>>1; if(x<=mid) solve(p<<1,l,mid,x,y); if(y>mid) solve(p<<1|1,mid+1,r,x,y); tree[p].x=tree[p<<1].x+tree[p<<1|1].x;}void insert1(int p,int l,int r,int x,int val){ if(l==r){tree[p].x=1,tree[p].id=val;return;} int mid=l+r>>1; if(x<=mid) insert1(p<<1,l,mid,x,val); else insert1(p<<1|1,mid+1,r,x,val); tree[p].x=tree[p<<1].x+tree[p<<1|1].x;}void spfa(){ deque<int>q; for(int i=1;i<=tot;++i) d[i]=1LL<<60;d[1]=0; q.push_back(1);inq[1]=1; while(!q.empty()){ int x=q.front();q.pop_front();inq[x]=0; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(d[x]+data[i].val<d[y]){ d[y]=d[x]+data[i].val; if(!inq[y]){ if(!q.empty()&&d[y]<d[q.front()]) q.push_front(y); else q.push_back(y);inq[y]=1; } } } }}int main(){// freopen("a.in","r",stdin); n=read();s=read()+100001; build(1,1,treen); for(int i=1;i<=n;++i){ a[i].x=read()+100001,a[i].y=read()+100001; }add(1,2,s-a[n].x);add(1,3,a[n].y-s); for(int i=n;i>=1;--i){ id1=++tot;id2=++tot; solve(1,1,treen,a[i].x,a[i].y); insert1(1,1,treen,a[i].x,id1); insert1(1,1,treen,a[i].y,id2); }id1=id2=++tot;solve(1,1,treen,1,treen); spfa(); printf("%lld\n",d[tot]); return 0;}
阅读全文
0 0
- poj2374 Fence Obstacle Course(线段树+建图spfa)
- poj2374 Fence Obstacle Course
- POJ2374-Fence Obstacle Course
- POJ2374 Fence Obstacle Course——线段树+动态规划
- [线段树]POJ 2374 Fence Obstacle Course
- TOJ 1600 Fence Obstacle Course -- 线段树,链表
- POJ 2374 Fence Obstacle Course 线段树优化DP
- POJ 2374 Fence Obstacle Course(线段树+动态规划)
- pku2374 Fence Obstacle Course
- poj 2374 Fence Obstacle Course
- POJ 2374Fence Obstacle Course
- POJ 2374 Fence Obstacle Course(map优化DP)
- [BZOJ1644][Usaco2007 Oct]Obstacle Course 障碍训练课(spfa)
- [BZOJ1644][Usaco2007Oct]Obstacle Course 障碍训练课(spfa)
- 线段树与动态规划(例题:poj2374,HDU3016)
- BZOJ3387 [USACO2004 Dec] Fence Obstacle Course栅栏行动
- BZOJ3387 [Usaco2004 Dec]Fence Obstacle Course栅栏行动
- BZOJ3387: [Usaco2004 Dec]Fence Obstacle Course栅栏行动
- 添加最少字符到数组中组合成回文
- 异步加载和延迟加载
- 原创作品 | 盘搜搜-极速搜索你想要的一切资源-爬虫学习项目总结
- day03 JavaScript
- 前端面试题
- poj2374 Fence Obstacle Course(线段树+建图spfa)
- [DP] UVA11548
- C++之过载函数
- Hive之 hive-1.2.1 + hadoop 2.7.4 集群安装
- HDU
- java作业4
- YTU.1989: 打印直角三角形
- 输出连续相同的子数组
- 4865fa85d9ee28bfab97d073a3dde8a3 病毒分析