这题就是个暴力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;
}