【BZOJ1922】大陆争霸

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1922


 

涨姿势了,,,这下不只是复习了。。。

此题可以认为是一种变相的最短路,嗯,有限制条件的最短路。

设dist1[i]表示到达某个结点的最短时间,dist2[i]表示可以进入某个结点的最短时间,显然,真正进入的最短时间是max(dist1[i],dist2[i])。对于每一个用来更新其他结点的结点,我们用他实际进入的时间去更新与他相邻的城市的到达时间,依赖于他的城市的可进入时间,并且依赖于他的城市的入度减1。每次更新都要把入度为0的点加入优先队列,不管是原先就为0,还是减1后为0。

另外提一点,不要把读入优化直接传入参数,顺序会变!别问我怎么知道的。。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5  
 6 using namespace std;
 7  
 8 inline int get_num() {
 9     int num = 0;
10     char c = getchar();
11     while (c < '0' || c > '9') c = getchar();
12     while (c >= '0' && c <= '9')
13         num = num * 10 + c - '0', c = getchar();
14     return num;
15 }
16  
17 const int maxn = 3e3 + 5, maxm = 7e4 + 5, inf = 0x3f3f3f3f;
18  
19 int head[maxn], eid, head2[maxn], eid2, ind[maxn];
20  
21 struct Edge {
22     int v, w, next;
23 } edge[maxm], edge2[maxm];
24  
25 inline void insert(int u, int v, int w) {
26     edge[++eid].v = v;
27     edge[eid].w = w;
28     edge[eid].next = head[u];
29     head[u] = eid;
30 }
31  
32 inline void insert2(int u, int v) {
33     edge2[++eid2].v = v;
34     edge2[eid2].next = head2[u];
35     head2[u] = eid2;
36 }
37  
38 int dist1[maxn], dist2[maxn], vis[maxn];
39  
40 struct node {
41     int id, dist;
42     node(int id, int dist) : id(id), dist(dist) {}
43     bool operator < (const node& rhs) const {
44         return dist > rhs.dist;
45     }
46 };
47  
48 priority_queue<node> q;
49  
50 inline void dijkstra() {
51     memset(dist1, inf, sizeof(dist1));
52     dist1[1] = 0;
53     q.push(node(1, 0));
54     while (!q.empty()) {
55         int u = q.top().id;
56         q.pop();
57         if (vis[u]) continue;
58         vis[u] = 1;
59         int td = max(dist1[u], dist2[u]);
60         for (int p = head[u]; p; p = edge[p].next) {
61             int v = edge[p].v, w = edge[p].w;
62             if (dist1[v] > td + w) {
63                 dist1[v] = td + w;
64                 if (!ind[v]) q.push(node(v, max(dist1[v], dist2[v])));
65             }
66         }
67         for (int p = head2[u]; p; p = edge2[p].next) {
68             int v = edge2[p].v;
69             --ind[v], dist2[v] = max(dist2[v], td);
70             if (!ind[v]) q.push(node(v, max(dist1[v], dist2[v])));
71         }
72     }
73 }
74  
75 int main() {
76     int n = get_num(), m = get_num();
77     for (int i = 1; i <= m; ++i) {
78         int u = get_num(), v = get_num(), w = get_num();
79         if (u != v) insert(u, v, w);
80     }
81     for (int i = 1; i <= n; ++i) {
82         ind[i] = get_num();
83         for (int j = 1; j <= ind[i]; ++j) {
84             int x = get_num();
85             insert2(x, i);
86         }
87     }
88     dijkstra();
89     printf("%d", max(dist1[n], dist2[n]));
90     return 0;
91 }
AC代码

 

posted @ 2018-11-03 15:45  Mr^Kevin  阅读(241)  评论(0编辑  收藏  举报