BZOJ3389 [Usaco2004 Dec]Cleaning Shifts安排值班

裸的最短路呢。。。

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

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

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

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

最后答案就是dis[T]

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

 

 1 /**************************************************************
 2     Problem: 3389
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:652 ms
 7     Memory:33064 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12 #include <vector>
13 #include <queue>
14  
15 using namespace std;
16 const int inf = (int) 1e9;
17 const int N = 1000005;
18 const int M = N * 2;
19 struct edges{
20     int next, to, v;
21 } e[M];
22 struct heap_node{
23     int v, to;
24 } NODE;
25 inline bool operator < (const heap_node &a, const heap_node &b){
26     return a.v > b.v;
27 }
28  
29 int n, d[N], T;
30 int tot, first[N];
31 bool vis[N];
32  
33 priority_queue <heap_node> h;
34  
35 inline int read(){
36     int x = 0, sgn = 1;
37     char ch = getchar();
38     while (ch < '0' || ch > '9'){
39         if (ch == '-') sgn = -1;
40         ch = getchar();
41     }
42     while (ch >= '0' && ch <= '9'){
43         x = x * 10 + ch - '0';
44         ch = getchar();
45     }
46     return sgn * x;
47 }
48  
49 inline void add_edge(int x, int y, int z){
50     e[++tot].next = first[x], first[x] = tot;
51     e[tot].to = y, e[tot].v = z;
52 }
53  
54 inline void add_to_heap(const int p){
55     for (int x = first[p]; x; x = e[x].next)
56         if (d[e[x].to] == inf){
57             NODE.v = e[x].v + d[p], NODE.to = e[x].to;
58             h.push(NODE);
59         }
60 }
61  
62 int Dijkstra(int S){
63     int p;
64     for (p = 1; p <= T; ++p) d[p] = inf;
65     while (!h.empty()) h.pop();
66     d[S] = 0, add_to_heap(S);
67     while (!h.empty()){
68         if (d[h.top().to] != inf){
69             h.pop();
70             continue;
71         }
72         p = h.top().to;
73         d[p] = h.top().v;
74         h.pop();
75         add_to_heap(p);
76     }
77     return d[T] == inf ? -1 : d[T];
78 }
79  
80 int main(){
81     n = read(), T = read();
82     int i, x, y;
83     for (i = 1; i <= T; ++i)
84         add_edge(i, i - 1, 0);
85     for (i = 1; i <= n; ++i){
86         x = read(), y = read();
87         add_edge(x - 1, y, 1);
88     }
89     printf("%d\n", Dijkstra(0));
90     return 0;
91 }
View Code

 (p.s. Orz iwtwiioi 贪心什么的太神了)

转载于:https://www.cnblogs.com/rausen/p/4080130.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值