POJ 3594 Escort of Dr. Who How(最短路+枚举)

题意:有n个城市道路,每个道路只能再一段区间[b,e]内可行,有给出每条道路的经过时间,问从出发开始时间st到结束最快结束时间en,的差en-st最小是多少。

思路:由于出发时间是不定的,当然可以用dfs暴搜,不过复杂度是肯定不能承受的,所以我们可以枚举开始时间start,这样就能对每个路段进行限制,在处理路段时,假如到达一个路段的时间为t0,只有满足下列条件,这条路段才是可行的(不包括c>e-b,因为这种情况开始就可以排除) 条件:t0+c <= e,然后经过完这条线路时,此路段结束时间为 max{t0+c,b+c}。

算法:对出发时间st从小到大枚举,每次bfs,dij求最短路时更新时间差,直到对于一个st*,不存在可行路径,返回最小值,这个值就是答案,我们可以证明对于一个出发时间st,他的解包括了st*的解(st*>st),因为考虑一个st时,我们完全可以延后到st*在出发!所以最后得到的值是最优的。

PS:话说最近做的枚举题已经超过了图论了.......

  
    
#include < iostream >
#include
< cstdio >
#include
< algorithm >
#include
< memory.h >
#include
< cmath >
#include
< bitset >
#include
< queue >
#include
< vector >
using namespace std;

const int BORDER = ( 1 << 20 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 1105 ;
const int INF = 1000000000 ;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))

#define SET_NODE(no,a,b) {no.u=a;no.val=b;}

typedef
struct {
int u;
int val;
}Node;
typedef
struct {
int v,next;
int b,e;
int c;
}Edge;

Edge edge[MAXN
* MAXN];
Node t_node,node;
int n,m,s,t,index,mmin,mmax;
int net[MAXN],tim[MAXN];
bool visit[MAXN];

bool operator < ( const Node & a, const Node & b)
{
return a.val > b.val;
}
void add_edge( const int & u, const int & v, const int & b,
const int & e, const int & c)
{
edge[index].v
= v;
edge[index].b
= b;
edge[index].e
= e;
edge[index].c
= c;
edge[index].next
= net[u];
net[u]
= index ++ ;
}
int init()
{
index
= 0 ;
CLR(visit,
0 );
CLR(net,
- 1 );
CLR(tim,
127 );
return 0 ;
}
int input()
{
int i,j,u,v,b,e,c;
for (i = 0 ; i < m; ++ i)
{
scanf(
" %d%d%d%d%d " , & u, & v, & b, & e, & c);
if (c > e - b)
continue ;
add_edge(u,v,b,e,c);
}
return 0 ;
}
int bfs( const int & tim_st)
{
int u,v,tmp,cur,i;
priority_queue
< Node > que;
while ( ! que.empty())
que.pop();
SET_NODE(t_node,s,tim_st);
que.push(t_node);
while ( ! que.empty())
{
node
= que.top();
que.pop();
u
= node.u;
cur
= node.val;
if (u == t)
return cur - tim_st;
for (i = net[u]; i != - 1 ; i = edge[i].next)
{
v
= edge[i].v;
tmp
= MAX(cur,edge[i].b);
tmp
+= edge[i].c;
if (tmp > edge[i].e)
continue ;
if (tmp > tim[v])
continue ;
tim[v]
= tmp;
SET_NODE(t_node,v,tmp);
que.push(t_node);
}
}
return - 1 ;
}
int work()
{
int i,j,ans,tmp;
ans
= INF;
mmin
= INF;
mmax
= - 1 ;
for ( i = net[s]; i != - 1 ; i = edge[i].next)
{
mmin
= MIN(mmin,edge[i].b);
mmax
= MAX(mmax,edge[i].e);
}
for ( i = mmin; i <= mmax; ++ i)
{
CLR(tim,
127 );
tmp
= bfs(i);
if (tmp == - 1 )
break ;
ans
= MIN(ans,tmp);
}
if (ans == INF)
printf(
" Impossible\n " );
else
OUT(ans);
return 0 ;
}
int main()
{
while (scanf( " %d%d%d%d " , & n, & m, & s, & t) != EOF)
{
init();
input();
work();
}
return 0 ;
}

 

你可能感兴趣的:(poj)