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;
}

  

原文地址:https://www.cnblogs.com/beiyuoi/p/6039676.html