B. Greg and Graph
...大约 1 分钟
题目
题意
- 输入 n(1≤n≤500) 表示 n 个点的有向完全图,然后输入 n*n 的邻接矩阵 a,其中 a[i][j] 表示 i 到 j 的边权,范围 [1,1e5](特例是 a[i][i]=0)。
- 图的节点编号从 1 开始。
- 然后输入 1~n 的排列,表示我要一个个地删除图上的点,每删除一个点,这个点的出边和入边都会被删除。
- 输出 n 个数,第 i 个数表示第 i 次删除之前,所有剩余点对的最短路之和。
思路
- Floyd
- Floyd算法差点可以倒着a的顺序插入,这样节省了一次建图
代码
const int N = 510;
int f[N][N];
int n;
int a[N],ans[N];
void floyd(int tar,int ed)
{
for (int u = 0; u < n;u ++)
{
for (int v = 0; v < n;v ++)
{
f[a[u]][a[v]] = min(f[a[u]][a[v]], f[a[u]][tar] + f[tar][a[v]]);
}
}
}
void solve()
{
cin >> n;
for (int i = 0; i < n;i ++)
for (int j = 0; j < n;j ++)
cin >> f[i][j];
for (int i = 0; i < n;i ++)
{
cin >> a[i];
a[i]--;
}
reverse(a, a + n);
for (int i = 0; i < n;i ++)
{
int add = a[i];
floyd(add, i);
int res = 0;
for (int u = 0; u <= i;u ++)
{
for (int v = 0; v <= i;v ++)if(u != v)
{
res += f[a[u]][a[v]];
// debug3(u, v, f[u][v]);
}
}
ans[n - i - 1] = res;
}
for (int i = 0; i < n;i ++)
cout << ans[i] << " ";
}
Powered by Waline v2.15.5