POJ 1062 昂贵的聘礼 (最短路+枚举)
题意:给定n个物品的关系和等级限制,问再等级限制之内,最少花多少钱能到达第一种物品。
思路:一年前做的题,那时死活不会做,现在看看能想到枚举了,(枚举变量+各种算法)现在很常见了,枚举可行的等级区间,对每个区间求最短路+heap,O(mnlogn)的复杂度,还是能过的,又偷懒了,用priority_queue.....
#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;
}