Codeforces Round #581 (Div. 2) C - Anna, Svyatoslav and Maps
题目
http://codeforces.com/contest/1204/problem/C
题意
给你一个图,然后给你一个路径,要求你把这条路径缩短,如果这个点是最短路上的点,就可以删除(起始点和结束点不能删除)。
题解
先跑一边弗洛伊德(floyd)然后用动态数组储存答案。
把1(起点)加入动态数组,然后沿着题目给的路径序列遍历,
如果数组中的最后一个顶点到当前遍历到的顶点的最短路不等于原序列中两点的距离,则答案加上i-1
遍历完之后在最后加上 m(终点)
代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int g[200][200],a[1000005];
vector<int> v;
int main()
{
int n,m;
v.clear();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%1d",&g[i][j]);
if(i==j) g[i][j] = 0;
else if(g[i][j]!=1)
g[i][j] = INF;
}
}
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
v.push_back(1);
for(int i=2;i<=m;i++)
{
if (g[a[v.back()]][a[i]] != i - v.back())
v.push_back(i - 1);
}
v.push_back(m);
printf("%d\n",v.size());
for(int i=0;i<v.size();i++)
{
printf("%d",a[v[i]]);
if(i!=v.size()-1)
printf(" ");
}
puts("");
return 0;
}