[SDOI2010]大陆争霸

Solution

有些城市必须在某些城市被破坏之后才能进入,例如 (v) 必须在 (u) 之前到,那么 (v) 的最短路就必须先被更新,这实际上是一个拓扑关系。我们必须要同时满足拓扑图的更新顺序和 Dijstra 的贪心策略。这个问题的解决办法就是在跑最短路的时候同时维护拓扑图的更新,当拓扑图中一个节点 (u) 的所有前驱都被更新后,才能将 (u) 加入到最短路更新队列,这样就保证了正确性。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define N 3007
#define M 700007

inline int read(){
    int x=0,flag=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
    return flag? x:-x;
}

struct Node{
    int pos,dis;
    Node(int pos_=0,int dis_=0):pos(pos_),dis(dis_){}
    bool operator <(const Node &X)const{return X.dis<dis;}
};

struct E{
    int next,to,dis;
}e[M<<1];
int head[N],cnt=0,tot[N],to[N][N];

priority_queue<Node> Q;

inline void add(int id,int to,int dis){
    e[++cnt]=(E){head[id],to,dis};
    head[id]=cnt;
}

bool vis[N];
int n,m,in[N],ans[N],dis[N],lim[N];
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),d=read();
        add(u,v,d);
    }
    for(int i=1;i<=n;i++){
        in[i]=read();
        for(int j=1;j<=in[i];j++){
            int v=read();
            to[v][++tot[v]]=i;
        }
    }
    memset(dis,63,sizeof(dis));
    dis[1]=ans[1]=0,Q.push(Node(1,0));
    while(!Q.empty()){
        Node t=Q.top(); Q.pop();
        int u=t.pos;
        if(vis[u]) continue;
        else vis[u]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(dis[v]>ans[u]+e[i].dis){
                dis[v]=ans[u]+e[i].dis;
                if(!in[v]){
                    ans[v]=max(dis[v],lim[v]);
                    Q.push(Node(v,ans[v]));
                }
            }
        }
        for(int i=1;i<=tot[u];i++){
            int v=to[u][i];
            lim[v]=max(lim[v],ans[u]);
            if(!(--in[v])){
                ans[v]=max(dis[v],lim[v]);
                Q.push(Node(v,ans[v]));
            }
        }
    }
    printf("%d",ans[n]);
}
/*
6 6
1 2 1
1 4 3
2 3 1
2 5 2
4 6 2
5 3 2
0
0
0
1 3
0
2 3 5
*/
原文地址:https://www.cnblogs.com/wwlwQWQ/p/14342889.html