这里是问题链接:http://codeforces.com/contest/295/problem/B
greg有一个加权有向图,由n个顶点组成。在这个图中,任何一对不同的顶点在两个方向上都有一条边格雷格喜欢玩图形,现在他发明了一种新游戏:
这个游戏由n个步骤组成。
在第i步,格雷戈从图中删除顶点数XI。当Greg移除一个顶点时,他也会移除所有进出该顶点的边。
在执行每个步骤之前,greg想知道所有剩余顶点对之间最短路径的长度之和。最短路径可以通过任何剩余的顶点。
帮助Greg,在每个步骤之前打印所需总和的值。
输入:
第一行包含整数n(1≤n≤500)-图中的顶点数。
接下来的n行各包含n个整数-图的邻接矩阵:第i行aij中的第j个数(1 ≤ aij ≤ 105, aii = 0)表示从顶点i到顶点j的边的权重。
下一行包含n个不同的整数:X1、x2、x2、……(格雷戈1)。
输出:
打印n个整数-第i个数字等于第i步前所需的和。
因此,基本上我的方法是在删除任何顶点之前运行Floyd Warshall算法,对于删除,我只需在行和列的邻接矩阵中将要删除的顶点的值设置为INT_MAX
。
基本上,这个循环在main
for (int h = 0; h < n; h++)
{
func();
int val = arr[h]; // arr contains the vertices to be deleted
for ( i = 1; i <= n; i++ )
dist[val][i] = INT_MAX;
for ( i = 1; i <= n; i++ )
dist[i][val] = INT_MAX;
}
这是我对flloyd warshall算法的实现:
void func ()
{
//int i,j,k;
ans = 0;
for ( i = 1; i <= n; i++ )
{
for ( j = 1; j <= n; j++ )
{
if (i == j)
val[i][j][0] = 0;
else if (dist[i][j] != 0)
val[i][j][0] = dist[i][j];
else
val[i][j][0] = INT_MAX;
}
}
for (k = 1; k <= n; k++)
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
val[i][j][k] = min(val[i][j][k-1],val[i][k][k-1]+val[k][j][k-1]);
//int ans = 0;
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
ans = ans + val[i][j][n];
cout<<ans<<"\t";
}
这里,
val
是我创建的全局三维矩阵,arr
包含要删除的顶点但是,当我运行这个逻辑时,它只在一开始给出正确的答案,即没有删除顶点。但在那之后,它给出了一个错误的值。我不明白为什么?我的逻辑不正确吗? 最佳答案
有一件事看起来很奇怪,那就是在最后你要计算所有剩余顶点对的和,但是你的循环只是覆盖所有顶点:
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
ans = ans + val[i][j][n];