BZOJ 1922 大陆争霸

神奇Dij
不是很懂
%hzwer代码

#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

int read(){
	int x=0, f=1;char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch>='0' && ch<='9'){x=x*10+(ch-'0');ch=getchar();}
	return x*f;
}

const int MAXN=3011;
const int MAXM=70111;
const int INF=1034567890;

int N, M;

struct Vert{
	int FE;
	int Deg;
	int Dis, Wait;
	bool Vis;
} V[MAXN];

struct Edge{
	int x, y, next;
	int l;
} E[MAXM];

int Ecnt=0;

void addE(int a, int b, int c){
	++Ecnt;
	E[Ecnt].x=a;E[Ecnt].y=b;E[Ecnt].l=c;
	E[Ecnt].next=V[a].FE;V[a].FE=Ecnt;
}

int P[MAXN][MAXN], Pcnt[MAXN];

priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > PQ;

void Dij(){
	
	for(int i=1;i<=N;++i)
		V[i].Dis=INF;
	
	PQ.push(make_pair(0, 1));
	V[1].Dis=0;
	
	int at, di;
	while(!PQ.empty()){
		at=PQ.top().second;PQ.pop();
		if(V[at].Vis)	continue;
		V[at].Vis=true;
		di=max(V[at].Dis, V[at].Wait);
		for(int k=V[at].FE, to;k>0;k=E[k].next){
			to=E[k].y;
			if(di+E[k].l<V[to].Dis){
				V[to].Dis=di+E[k].l;
				if(V[to].Deg==0)
					PQ.push(make_pair(max(V[to].Dis, V[to].Wait), to));
			}
		}
		for(int i=1, to;i<=Pcnt[at];++i){
			to=P[at][i];
			--V[to].Deg;V[to].Wait=max(V[to].Wait, di);
			if(V[to].Deg==0)
				PQ.push(make_pair(max(V[to].Wait, V[to].Dis), to));
		}
	}
}

int main(){
	
	N=read();M=read();
	for(int i=1, a, b, c;i<=M;++i){
		a=read();b=read();c=read();
		if(a==b)	continue;/**/
		addE(a, b, c);
	}
	for(int i=1, c;i<=N;++i){
		c=read();
		V[i].Deg=c;
		for(int j=1, p;j<=c;++j){
			p=read();
			P[p][++Pcnt[p]]=i;
		}
	}
	Dij();
	
	printf("%d\n", max(V[N].Dis, V[N].Wait));
	
	return 0;
}

/*
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

5

*/
posted @ 2018-05-28 10:25  Pickupwin  阅读(152)  评论(0编辑  收藏  举报