您的位置:首页 > 其它

BZOJ3389 [Usaco2004 Dec]Cleaning Shifts安排值班

2014-11-06 22:39 316 查看
裸的最短路呢。。。

建图还是有些微妙的。。。但是感觉不快啊。。。

每个时间点建一个点,然后我们建图分两步:

(1)i 时间点向 i - 1 号时间点连一条有向边

(2)若有一头牛[l, r],则 l - 1向 r连一条边

最后答案就是dis[T]

想想就觉得非常巧妙。。。但是慢啊。。。

/**************************************************************
Problem: 3389
User: rausen
Language: C++
Result: Accepted
Time:652 ms
Memory:33064 kb
****************************************************************/

#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;
const int inf = (int) 1e9;
const int N = 1000005;
const int M = N * 2;
struct edges{
int next, to, v;
} e[M];
struct heap_node{
int v, to;
} NODE;
inline bool operator < (const heap_node &a, const heap_node &b){
return a.v > b.v;
}

int n, d
, T;
int tot, first
;
bool vis
;

priority_queue <heap_node> h;

inline int read(){
int x = 0, sgn = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-') sgn = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return sgn * x;
}

inline void add_edge(int x, int y, int z){
e[++tot].next = first[x], first[x] = tot;
e[tot].to = y, e[tot].v = z;
}

inline void add_to_heap(const int p){
for (int x = first[p]; x; x = e[x].next)
if (d[e[x].to] == inf){
NODE.v = e[x].v + d[p], NODE.to = e[x].to;
h.push(NODE);
}
}

int Dijkstra(int S){
int p;
for (p = 1; p <= T; ++p) d[p] = inf;
while (!h.empty()) h.pop();
d[S] = 0, add_to_heap(S);
while (!h.empty()){
if (d[h.top().to] != inf){
h.pop();
continue;
}
p = h.top().to;
d[p] = h.top().v;
h.pop();
add_to_heap(p);
}
return d[T] == inf ? -1 : d[T];
}

int main(){
n = read(), T = read();
int i, x, y;
for (i = 1; i <= T; ++i)
add_edge(i, i - 1, 0);
for (i = 1; i <= n; ++i){
x = read(), y = read();
add_edge(x - 1, y, 1);
}
printf("%d\n", Dijkstra(0));
return 0;
}


View Code
(p.s. Orz iwtwiioi 贪心什么的太神了)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: