Vijos 1404 遭遇战

描述

今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC的人誓死不屈,即将于恐怖分子展开激战,准备让一个人守着A区,这样恐怖分子就不能炸掉服务器了。(一个人就能守住??这人是机械战警还是霹雳游侠?)
但是问题随之出现了,由于DustII中风景秀丽,而且不收门票,所以n名反恐精英们很喜欢在这里散步,喝茶。他们不愿意去单独守在荒无人烟的A区,在指挥官的一再命令下,他们终于妥协了,但是他们每个人都要求能继续旅游,于是给出了自己的空闲时间,而且你强大的情报系统告诉了你恐怖份子计划的进攻时间(从s时刻到e时刻)。
当然,精明的SQC成员不会为你免费服务,他们还要收取一定的佣金(注意,只要你聘用这个队员,不论他的执勤时间多少,都要付所有被要求的佣金)。身为指挥官的你,看看口袋里不多的资金(上头真抠!),需要安排一个计划,雇佣一些队员,让他们在保证在进攻时间里每时每刻都有人员执勤,花费的最少资金。

解题报告:
这题解法实在太多,这里介绍最短路算法,这题其实可以转化为最短路模型,以每个时间为一个节点(如果数据范围大,当然是可以离散的),于是这样就可以转化为求s到e的最短路了.
关于建边:
1.对于输入的(a,b),我们连(a,b+1)
2.为了保证在同一个区间内可以连通且不影响答案,连(i+1,i,0)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=1e4+5,M=9e4+5;
int n,s,e,head[M],dis[M<<2],to[M<<2],nxt[M<<2],num=0;
void link(int x,int y,int z){nxt[++num]=head[x];to[num]=y;dis[num]=z;head[x]=num;}
int q[M*10],mod=M*10;bool vis[M];ll f[M];
void spfa(){
	int t=0,sum=1,x,u;ll inf;
	memset(f,127/3,sizeof(f));inf=f[0];
	f[s]=0;q[sum]=s;vis[s]=true;
	while(t!=sum){
		t++;if(t==mod)t=0;x=q[t];
		for(int i=head[x];i;i=nxt[i]){
			u=to[i];
			if(f[x]+dis[i]<f[u]){
				f[u]=f[x]+dis[i];
				if(!vis[u]){
					vis[u]=true;
					sum++;if(sum==mod)sum=0;
					q[sum]=u;
				}
			}
		}
		vis[x]=false;
	}
	if(f[e+1]!=inf)
		printf("%lld\n",f[e+1]);
	else puts("-1");
}
void work()
{
	scanf("%d%d%d",&n,&s,&e);
	int x,y,v;
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&x,&y,&v);
		if(x>y)swap(x,y);
		if(x>e || y<s)continue;
		link(Max(x,s),Min(y,e)+1,v);
	}
	for(int i=e+2;i>=s;i--)
		link(i,i-1,0);
	spfa();
}

int main()
{
	work();
	return 0;
}

posted @ 2017-09-11 21:24  PIPIBoss  阅读(147)  评论(0编辑  收藏  举报