n个点,每个点有权值 ai ,从i到j的边权为为: (aj−ai)3 。问从1到达k的最短路,不能到达和路径长小于3输出? 其它输出长度
可能出现负环,用SPFA
出现负环时 负环可达的都应该输出?,入队次数超过n次,将距离置为负无穷,且之后再不入队
//WA1 出现负环时 负环可达的都应该输出?,入队次数超过n次,将距离置为负无穷,且之后再不入队,题意不清。。 unidirectional 单向的意思
#include <cstdio>
#include <algorithm>
#include <stack>
#include <cstring>
using namespace std;
const int MAXN=222;
const int MAXM=MAXN*MAXN/2;
const int INF=0x3f3f3f3f;
int T,lev[MAXN],head[MAXN],to[MAXM<<1],ne[MAXM<<1],wt[MAXM<<1],n,m,q,dist[MAXN],ecnt;
void init()
{
ecnt=0;
memset(head,0,sizeof(head));
}
void addedge(int a,int b,int c)
{
ne[++ecnt]=head[a];
head[a]=ecnt;
to[ecnt]=b;
wt[ecnt]=c;
}
stack<int> st;
int vis[MAXN],inq[MAXN];
int spfa(int s)//s为源点,t为终点
{
while(!st.empty())
st.pop();
for(int i=1;i<=n;i++)
dist[i]=INF,vis[i]=0,inq[i]=0;
dist[s]=0;
st.push(s);
inq[s]=1;
while(!st.empty())
{
int fr=st.top();
st.pop();
inq[fr]=0;
for(int k=head[fr];k;k=ne[k])
{
int v=to[k];
if(dist[v]>dist[fr]+wt[k])
{
dist[v]=dist[fr]+wt[k];
if(inq[v])
continue;
if(++vis[v]>=n)//有负环
dist[v]=-INF;
if(vis[v]<=n)
st.push(v);
inq[v]=1;
}
}
}
return 1;
}
int main()
{
int ta,tb,tc;
scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&lev[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&ta,&tb);
tc=lev[tb]-lev[ta];
tc=tc*tc*tc;
addedge(ta,tb,tc);
}
scanf("%d",&q);
int ans;
spfa(1);
printf("Case %d:\n",kase);
for(int i=0;i<q;i++)
{
scanf("%d",&ta);
if(dist[ta]<3||dist[ta]==INF)
printf("?\n");
else
printf("%d\n",dist[ta]);
}
}
return 0;
}