思路:一个有多层次的图,求1到n的最短路,把每一层图都拆成两个点,一个点入,一个点出,然后建图就好了,建图详见代码
#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int maxn = 3*1e5+7;
vector<pair<int,int> >e[maxn];
int d[maxn],inq[maxn],s,t,n,m,c;
void spfa()
{
queue<int>q;
for(int i = 0;i<=3*n;i++)
d[i]=inf;
memset(inq,0,sizeof(inq));
d[s]=0;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
inq[u]=0;
for(int i = 0;i<e[u].size();i++)
{
int v= e[u][i].first;
int w= e[u][i].second;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
if(!inq[v])
q.push(v);
inq[v]=1;
}
}
}
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
for(int i = 0;i<=3*n;i++)
e[i].clear();
scanf("%d%d%d",&n,&m,&c);
for(int i= 1;i<n;i++)
{
e[n+i].push_back(make_pair(n*2+i+1,c));
e[n+i+1].push_back(make_pair(n*2+i,c));
}
for(int i = 1;i<=n;i++)
{
int la;
scanf("%d",&la);
e[i].push_back(make_pair(n+la,0));
e[2*n+la].push_back(make_pair(i,0));
}
for(int i = 1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
e[u].push_back(make_pair(v,w));
e[v].push_back(make_pair(u,w));
}
s=1,t=n;
spfa();
if(d[n]==inf)
d[n]=-1;
printf("Case #%d: %d\n",cas++,d[n]);
}
}