intspfa(int s){fill(d, d + N, INF);
d[s]=0;
queue<int> q;
q.push(s);
inq[s]=true;while(q.size()){int u = q.front();
q.pop();
inq[u]=false;for(int v = h[u]; v !=-1; v = ne[v]){int j = e[v];if(d[u]+ w[v]< d[j]){
d[j]= d[u]+ w[v];if(inq[j]==false){
q.push(j);
inq[j]=true;}}}}return d[n];}
spfa 判断负环
最短路径最多经过 n - 1 个点,如 1 到 n
若最短路径经过的点 大于 n - 1,证明存在环,且为负环
另:可能负环不在源点经过的路径上,
可能在每一个点的路径上,
所以要先将每个点放进队列
boolspfa(){fill(d, d + N, INF);
d[1]=0;
queue<int> q;// 可能负环不在源点的路径上,// 可能在每一个点的路径上,// 所以要先将每个点放进队列for(int i =1; i <= n;++i){
q.push(i);
inq[i]=true;// cnt[i]++;}while(q.size()){int u = q.front();
q.pop();
inq[u]=false;for(int v = h[u]; v !=-1; v = ne[v]){int j = e[v];if(d[u]+ w[v]< d[j]){
d[j]= d[u]+ w[v];
cnt[j]= cnt[u]+1;if(inq[j]==false){
q.push(j);
inq[j]=true;// cnt[j]++;if(cnt[j]>= n)returnfalse;}}}}returntrue:}
Floyd
注意初始化
考虑存在重边情况
可能存在负权边的情况,判断条件 > INF / 2
constint N =210, INF =0x3f3f3f3f;int d[N][N], n, m, k;intfloyd(){for(int v =1; v <= n;++v)for(int i =1; i <= n;++i)for(int j =1; j <= n;++j)if(d[i][v]!= INF && d[v][j]!= INF && d[i][v]+ d[v][j]< d[i][j])
d[i][j]= d[i][v]+ d[v][j];}intmain(){fill(d[0], d[0]+ N * N, INF);
cin >> n >> m >> k;for(int i =1; i <= n;++i)
d[i][i]=0;// i 到 i 距离初始化为0while(m--){int a, b, c;
cin >> a >> b >> c;
d[a][b]=min(d[a][b], c);// 可能存在重边情况,取最小边权}floyd();while(k--){int a, b;
cin >> a >> b;if(d[a][b]> INF /2)// 注意这里的判断
cout <<"impossible"<< endl;else
cout << d[a][b]<< endl;}return0;}