记录一下这种题型,以防忘记。
题意:给出n个城市,每个城市都有一个拥挤度,从a到b的时间是(b的拥挤度-a的拥挤度)^3,点1为起点,求最短时间。
最后判断条件只要是最短路小于3或等于inf或位于负环上都输出问号,其他情况输出最小值即可。
如果有负环,遍历会超过n-1次
这题不适合邻接矩阵来做,可以用链式前向星存储,也可以直接用vector< edge >存储。
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=200+7;
int n,m,a[maxn][maxn],T,x,y,o;
struct edge{
int to,w;
edge(int a,int b){ to=a; w=b; }
};
vector<edge>sz[maxn];
int d[maxn],cnt[maxn],b[maxn];
bool vis[maxn];
int dis(int i,int j){
return (b[j]-b[i])*(b[j]-b[i])*(b[j]-b[i]);
}
void spfa(){
memset(d,inf,sizeof(d)); memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt)); d[1]=0; vis[1]=1; cnt[1]++;
queue<int>q; q.push(1);
while(!q.empty()){
int t=q.front(); q.pop();
vis[t]=0;
for(int i=0;i<sz[t].size();i++){
y=sz[t][i].to;
x=sz[t][i].w;
if(d[y]>x+d[t]){
d[y]=x+d[t];
if(!vis[y]&&cnt[y]<=n-1){ //注意判断
vis[y]=1;
q.push(y);
cnt[y]++; //区别点
}
}
}
}
}
int main(){
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++){
sz[i].clear();
cin>>b[i];
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>x>>y;
sz[x].push_back(edge(y,dis(x,y)));
}
spfa();
int tt; cin>>tt;
o++;
cout<<"Case "<<o<<":"<<endl;
while(tt--){
cin>>x;
if(d[x]<3||d[x]==inf||cnt[x]>=n-1) cout<<"?"<<endl;
else cout<<d[x]<<endl;
}
}
}