1. 程式人生 > >Bzoj1922: [Sdoi2010]大陸爭霸

Bzoj1922: [Sdoi2010]大陸爭霸

code OS source turn fill cnblogs memset back AC

題面

傳送門

Sol

走到一個點的前提是所有的影響它的點都走到,並且它的時間為那些點的時間\(max\)與自己的最短路的\(max\)
考慮\(Dijkstra\)
每次松弛時候,把它影響到的點的防護罩減\(1\)
如果某個點沒有後繼影響它的節點就丟到大根堆內
然後這個繼續松弛

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
const int _(3005);
const int
__(70005); typedef long long ll; IL int Input(){ RG int x = 0, z = 1; RG char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3
) + (c ^ 48); return x * z; } int n, first[_], cnt, m, d[_], vis[_]; ll dis[_], mxd[_]; struct Data{ int u; ll d; IL int operator <(RG Data B) const{ return d > B.d; } }; struct Edge{ int to, next, w; } edge[__]; vector <int> G[_]; priority_queue <Data> Q; IL void
Add(RG int u, RG int v, RG int w){ edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++; } IL ll Solve(){ Fill(dis, 127), mxd[1] = dis[1] = 0, Q.push((Data){1, 0}); while(!Q.empty()){ RG Data x = Q.top(); Q.pop(); if(vis[x.u]) continue; vis[x.u] = 1; for(RG int l = G[x.u].size(), i = 0; i < l; ++i){ RG int v = G[x.u][i]; mxd[v] = max(mxd[v], x.d); if(!--d[v]) Q.push((Data){v, max(mxd[v], dis[v])}); } for(RG int e = first[x.u]; e != -1; e = edge[e].next){ RG int v = edge[e].to, w = edge[e].w; if(vis[v]) continue; if(x.d + w < dis[v]){ dis[v] = x.d + w; if(!d[v]) Q.push((Data){v, max(mxd[v], dis[v])}); } } } return max(dis[n], mxd[n]); } int main(RG int argc, RG char* argv[]){ Fill(first, -1), n = Input(), m = Input(); for(RG int i = 1; i <= m; ++i){ RG int u = Input(), v = Input(), w = Input(); Add(u, v, w); } for(RG int i = 1; i <= n; ++i){ d[i] = Input(); for(RG int j = 1; j <= d[i]; ++j) G[Input()].push_back(i); } printf("%lld\n", Solve()); return 0; }

Bzoj1922: [Sdoi2010]大陸爭霸