B. Greg and Graph

题意:n个节点的图,每次操作删除一个节点。求每次操作之前,所有的图中的有序对(i, j)的最短路径之和。

思路:n <= 500, 弗洛伊德最短路径算法。因为每次的操作是删除节点,所以可以考虑将操作反着来,每次往图中添加节点,每添加一个节点更新一下最短路径。

总结:因为要添加的节点已经存储在了图中,所以不需要再将该节点作为终点去求最短路径了,只需要将该节点作为中转节点去求最短路径就可以。
debug一个数据溢出问题,调了半个小时。最后发现是在输出的时候对long long容器使用了(int v : ans)输出,真是个傻逼。

void solve(){
    int n;
    cin >> n;

    vector<vector<int>> am(n, vector<int>(n));
    vector<int> order(n);
    vector<long long> ans(n, 0);

    for (int i = 0; i < n; ++i){
        for (int j = 0; j < n; ++j){
            cin >> am[i][j];
        }
    }
    for (int i = 0; i < n; ++i){
        cin >> order[i];
        order[i] --;
    }

    vector<int> has;
    for (int i = n - 1; i >= 0; --i){
        int k = order[i];
        for (int u = 0; u < n; ++u){
            for (int v = 0; v < n; ++v){
                //checkMin(am[u][v], am[u][k] + am[k][v]);
                am[u][v] = min(am[u][v], am[u][k] + am[k][v]);
            }
        }
        for (int u = n - 1; u >= i; --u){
            for (int v = n - 1; v >= i; --v){
                ans[i] += am[order[u]][order[v]];
            }
        }
    }

    for (int i = 0; i < n; ++i){
        cout << ans[i] << " \n"[i == n - 1];
    }
}
posted @ 2024-05-06 10:44  _Yxc  阅读(7)  评论(0编辑  收藏  举报