BZOJ 2200 [Usaco2011 Jan]道路和航線 SPFA+heapDijkstra

~hsm~發表於2019-02-24

title

BZOJ 2200

code

#include<bits/stdc++.h>
using namespace std;
const int maxt=25e3+6,maxrp=15e5+6,inf=0x3f3f3f3f;
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1,ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
int ver[maxrp],edge[maxrp],Next[maxrp],head[maxt],len;
inline void add(int x,int y,int z)
{
	ver[++len]=y,edge[len]=z,Next[len]=head[x],head[x]=len;
}
int cnt,c[maxt];
inline void dfs(int x)
{
	for (int i=head[x];i;i=Next[i])
	{
		int y=ver[i];
		if (!c[y]) c[y]=cnt,dfs(y);
	}
}
int dist[maxt],vis[maxt],deg[maxt];
priority_queue<pair<int,int> >Q;
queue<int>q;
int main()
{
	int t,r,p,s;
	read(t);read(r);read(p);read(s);
	for (int i=1;i<=r;++i)
	{
		int x,y,z;
		read(x);read(y);read(z);
		add(x,y,z);add(y,x,z);
	}
	for (int i=1;i<=t;++i)
		if (!c[i])
			c[i]=++cnt,dfs(i);
	for (int i=1;i<=p;++i)
	{
		int x,y,z;
		read(x);read(y);read(z);
		add(x,y,z);
		++deg[c[y]];
	}
	memset(dist,0x7f,sizeof(dist));
	memset(vis,0,sizeof(vis));
	dist[s]=0;
	q.push(c[s]);
	for (int i=1;i<=cnt;++i)
		if (!deg[i]) q.push(i);
	while (!q.empty())
	{
		int tmp=q.front();
		q.pop();
		for (int i=1;i<=t;++i)
			if (c[i]==tmp)
				Q.push(make_pair(-dist[i],i));
		while (!Q.empty())
		{
			int x=Q.top().second;
			Q.pop();
			if (vis[x]) continue;
			vis[x]=1;
			for (int i=head[x];i;i=Next[i])
			{
				int y=ver[i],z=edge[i];
				if (dist[y]>dist[x]+z)
				{
					dist[y]=dist[x]+z;
					if (c[x]==c[y])
						Q.push(make_pair(-dist[y],y));
				}
				if (c[x]!=c[y] && !--deg[c[y]]) q.push(c[y]);
			}
		}
	}
	for (int i=1;i<=t;++i)
		if (dist[i]>inf) puts("NO PATH");
		else printf("%d\n",dist[i]);
	return 0;
}

相關文章