CF1204C-アンナ、Svyatoslavと地図
質問の意味:
トピックPortalは
、タイトルを読んで、言いたくありません。
ソリューション:
フロイドは、頂点間の最短経路と第1のRAN。P(1)の答えに加え、そして次に対象配列トラバーサルの経路に沿って、現在の反復の頂点からの最短距離の最後の頂点への答えは、元のシーケンスの2点間の距離よりも小さい場合と、一緒に答えpの(I-1)、および最後の加算P(M)の後にトラバースされる経路を横断し続けます
コード:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
#define LL long long
#define N 110
int e[N][N],ans[N*N*N];
int p[N*N*N],n,m,cnt;
void floyd() {
for(int k = 1 ; k <= n ; k++) {
for(int i = 1 ; i <= n ; i++) {
for(int j = 1 ; j <= n ; j++) {
e[i][j] = min(e[i][j],e[i][k] + e[k][j]);
}
}
}
}
int main(){
scanf("%d",&n);
getchar();
for(int i = 1 ; i <= n ; i++) {
for(int j = 1 ; j <= n ; j++) {
char t = getchar();
e[i][j] = (t == '1') ? 1 : INF;
if(i == j) e[i][j] = 0;
}
getchar();
}
scanf("%d",&m);
for(int i = 1 ; i <= m ; i++)
scanf("%d",&p[i]);
floyd();
ans[++cnt] = p[1];
int dis = 0;
for(int i = 2 ; i <= m ; i++) {
dis += e[p[i - 1]][p[i]];
if(dis > e[ans[cnt]][p[i]]){
ans[++cnt] = p[i - 1];
dis = e[ans[cnt]][p[i]];
}
}
ans[++cnt] = p[m];
printf("%d \n",cnt);
for(int i = 1 ; i <= cnt ; i++)
printf("%d ",ans[i]);
//system("pause");
return 0;
}