【GDOI2013模拟1】最短路

这题就是个暴力spfa。。。
我们就从节点1开始更新,每次更新一圈。

我们可以发现,每个完全子图暴力扫过以后就不需要再扫了(因为不会再优),所以就可以过了(判一判是否扫过就可以了)。


这题有个重构图的解法。就是对于每个完全子图构建成一个菊花图,而边权便是1/2,然后跑一遍spfa就可以了。

#include<cstdio>
#include<cstring>
#define N 100010
using namespace std;
struct node{int v,fr;}e[1000010];
int n,K,m,tail[N],cnt=0,a[1010][1010];
int f[N<<2],l=0,r=1,nr,d[N],tot=1;
bool bz[N],bz1[N];

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

void add(int u,int v) {e[++cnt]=(node){v,tail[u]}; tail[u]=cnt;}

int main()
{
	freopen("spfa.in","r",stdin);
//	freopen("spfa.out","w",stdout);
	n=read(),K=read(),m=read();
	for (int i=1;i<=m;i++)
		for (int j=1;j<=K;j++)
			a[i][j]=read(),add(a[i][j],i);
	f[1]=1,d[1]=1;
	while (l<r)
	{
		nr=r;tot++;
		while (l<r)
		{
			l++;
			for (int p=tail[f[l]],v;p;p=e[p].fr)
			{
				v=e[p].v;
				if (!bz[v])
				{
					for (int i=1;i<=K;i++)
						if (!bz1[a[v][i]])
						{
							d[a[v][i]]=tot;
							f[++nr]=a[v][i];
							bz1[a[v][i]]=1;
						}
					bz[v]=1;
				}
			}
		}
		r=nr;
		if (bz1[n]) break;
	}
	if (!bz1[n]) puts("-1");
	else printf("%d
",d[n]);
	return 0;
}
转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/11817571.html