这里是问题链接: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];

10-06 03:35