BZOJ 1922: [Sdoi2010]大陆争霸
Description
一个无向图,到一个点之前需要先到其他点,求从第一个点到第 \(n\) 点最短时间.
Sol
拓扑+Dijkstra.
跑Dijkstra的时候加上拓扑序...
用两个数组表示 到该点的最短路和到拓扑中最大的距离,入堆的时候需要对两个取 \(max\) .
Code
#include<cstdio> #include<cstring> #include<utility> #include<vector> #include<queue> #include<iostream> using namespace std; #define mpr make_pair typedef long long LL; typedef pair< LL,int > pr; const int N = 3005; int n,m; vector<pr> g[N];vector<int> h[N]; bool b[N];int p[N];LL d[N],w[N]; priority_queue<pr,vector<pr>,greater<pr> > q; inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar(); while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } void Dijkstra(int s){ memset(d,0x3f,sizeof(d)),memset(b,0,sizeof(b)); d[s]=w[s]=0;q.push(mpr(0,s)); for(int x;!q.empty();){ x=q.top().second,q.pop();if(b[x]) continue;b[x]=1; LL tmp=max(d[x],w[x]); for(int i=0;i<g[x].size();i++){ LL l=g[x][i].first;int v=g[x][i].second; if(tmp+l < d[v]){ d[v]=tmp+l; if(p[v] == 0) q.push(mpr(max(d[v],w[v]),v)); } }for(int i=0,v;i<h[x].size();i++){ v=h[x][i],w[v]=max(w[v],tmp),p[v]--; if(p[v] == 0) q.push(mpr(max(d[v],w[v]),v)); } } } int main(){ n=in(),m=in(); for(int i=1,u,v,l;i<=m;i++) u=in(),v=in(),l=in(),g[u].push_back(mpr(l,v)); for(int i=1,l,u;i<=n;i++) for(l=in();l--;) u=in(),h[u].push_back(i),++p[i]; Dijkstra(1); cout<<max(d[n],w[n])<<endl; return 0; }