BZOJ1922: [Sdoi2010]大陆争霸
由于本人头铁,这题搞了将近一上午还是爆零
于是颓题解
对于每个点分别记录两个值:到达这个点的最短时间 和 进入这个点的最短时间
前一个值用最短路更新,后一个值用保护它的点的最短路更新
所以本题中一个点的最短路就是 上边的两个值取 max
按题目的道理大力更新最短路即可
代码:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<queue>
using namespace std;
const int MAXN = 3005, MAXM = 70005;
struct EDGE{
int nxt, to, val;
EDGE(int NXT = 0, int TO = 0, int VAL = 0) {nxt = NXT; to = TO; val = VAL;}
}edge[MAXM << 1];
int n, m, totedge;
int head[MAXN], rem[MAXN], d1[MAXN], d2[MAXN];
bool vis[MAXN], pro[MAXN], to[MAXN];
priority_queue<pair<int,int> > q;
inline void add(int x, int y, int v) {
edge[++totedge] = EDGE(head[x], y, v);
head[x] = totedge;
return;
}
inline void dij() {
d1[1] = d2[1] = 0;
to[1] = true;
q.push(make_pair(0, 1));
while(!q.empty()) {
int x = q.top().second; q.pop();
if(vis[x]) continue;
vis[x] = true;
int cur = max(d1[x], d2[x]);
for(int i = head[x]; i; i = edge[i].nxt) {
int y = edge[i].to;
if(edge[i].val != 0x3f3f3f3f) {
if(d1[y] > cur + edge[i].val) {
to[y] = true;
d1[y] = cur + edge[i].val;
if(!rem[y]) q.push(make_pair(-max(d1[y], d2[y]), y));
}
} else {
--rem[y];
if(!rem[y]) {
d2[y] = cur;
if(to[y]) q.push(make_pair(-max(d1[y], d2[y]), y));
}
}
}
}
return;
}
int main() {
scanf("%d%d", &n, &m);
register int xx, yy, vv;
for(int i = 1; i <= m; ++i) {
scanf("%d%d%d", &xx, &yy, &vv);
if(xx == yy) continue;
add(xx, yy, vv);
}
for(int i = 1; i <= n; ++i) {
d1[i] = 0x3f3f3f3f;
d2[i] = 0;
scanf("%d", &vv);
rem[i] += vv;
pro[i] = vv;
while(vv--) {
d2[i] = 0;
scanf("%d", &xx);
add(xx, i, 0x3f3f3f3f);
}
}
dij();
printf("%d\n", max(d1[n], d2[n]));
return 0;
}
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/

浙公网安备 33010602011771号