Greg and Graph+floyd算法的应用

Greg and Graph

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Greg has a weighed directed graph, consisting of n vertices. In this graph any pair of distinct vertices has an edge between them in both directions. Greg
loves playing with the graph and now he has invented a new game:

  • The game consists of n steps.
  • On the i-th step Greg removes vertex number xi from
    the graph. As Greg removes a vertex, he also removes all the edges that go in and out of this vertex.
  • Before executing each step, Greg wants to know the sum of lengths of the shortest paths between all pairs of the remaining vertices. The shortest path can go through any remaining vertex. In other words, if we assume that d(i,?v,?u) is
    the shortest path between vertices v and u in the
    graph that formed before deleting vertex xi,
    then Greg wants to know the value of the following sum: .

Help Greg, print the value of the required sum before each step.

Input

The first line contains integer n (1?≤?n?≤?500) —
the number of vertices in the graph.

Next n lines contain n integers each — the graph
adjacency matrix: the j-th number in the i-th line aij (1?≤?aij?≤?105,?aii?=?0) represents
the weight of the edge that goes from vertex i to vertex j.

The next line contains n distinct integers: x1,?x2,?...,?xn (1?≤?xi?≤?n) —
the vertices that Greg deletes.

Output

Print n integers — the i-th number equals the required
sum before the i-th step.

Please, do not use the %lld specifier to read or write 64-bit integers in C++. It is preferred
to use the cin, cout streams of the %I64dspecifier.

Sample test(s)

input

1
0
1

output

0 

input

2
0 5
4 0
1 2

output

9 0 

input

4
0 3 1 1
6 0 400 1
2 4 0 1
1 1 1 0
4 1 2 3

output

17 23 404 0 
解决方案:可逆向的做,在一个没有点的图中,先加最后删去的那条边,算出总的最短路,以去点边的顺序不断加边,当把边补完时,即求出所有结果。这题啊要对floyd有一定的理解。
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#define MMAX 550
#define inf -1
using namespace std;
long long Map[MMAX][MMAX];
long long arra[MMAX];
long long r[MMAX];
bool vis[MMAX];
int n,m;
int main()
{
    int a,b,x;
    while(cin>>n)
    {
        memset(vis,false,sizeof(vis));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                cin>>Map[i][j];
            }
        for(int i=1; i<=n; i++)
        {
            cin>>arra[i];
        }
        for(int i=n; i>=1; i--)
        {
            vis[arra[i]]=true;
            for(int j=1; j<=n; j++)
                for(int k=1; k<=n; k++)
                {
                    if(Map[j][k]>Map[j][arra[i]]+Map[arra[i]][k])
                    {
                        Map[j][k]=Map[j][arra[i]]+Map[arra[i]][k];
                    }
                }
            long long sum=0;
            for(int j=1; j<=n; j++)
                for(int k=1; k<=n; k++)
                {
                    if(vis[j]&&vis[k])
                    {
                        sum+=Map[j][k];
                    }
                }

           r[i]=sum;
        }
        for(int i=1;i<n;i++){
            cout<<r[i]<<" ";
        }
        cout<<r[n]<<endl;

    }
    return 0;
}

Greg and Graph+floyd算法的应用,布布扣,bubuko.com

时间: 2024-10-03 13:46:26

Greg and Graph+floyd算法的应用的相关文章

codeforces 295B B. Greg and Graph(floyd+dp)

题目链接: codeforces 295B 题目大意: 给出n个点的完全有权有向图,每次删去一个点,求每次操作前整张图各个点的最短路之和. 题目分析: 首先删边对于我们来说是不好做的,所以我们想到了通过加点的方式逆向地做,那么加点怎么做呢? 其实就是一个我们很熟悉的算法:floyd,因为我们通常用的都是它的简化版本,所以可能很多人并不理解它的确切的思想. 在介绍这道题的具体解法之前,我先解释一下floyd,可能之后的问题就迎刃而解了. 首先floyd其实是动态规划,没有省略时的状态是这样定义的.

295B - Greg and Graph (floyd逆序处理)

题意:给出任意两点之间的距离,然后逐个删除这些点和与点相连的边,问,在每次删除前的所有点对的最短距离之和 分析:首先想到的是floyd,但是如果从前往后处理,复杂度是(500)^4,超时,我们从后往前处理,这样我们可以看作是添加点,而且这样的话每次只需要考虑添加点的缩进,所以复杂度是(500)^3,注意,我们每次添加一个点,就给他一个标记,代表这个点已经添加,然后算距离的时候,只有添加过的点才能加上距离 代码: #include <bits/stdc++.h> using namespace

数据结构:点对之间最短距离--Floyd算法

Floyd算法 Floyd算法 Dijkstra算法是用于解决单源最短路径问题的,Floyd算法则是解决点对之间最短路径问题的.Floyd算法的设计策略是动态规划,而Dijkstra采取的是贪心策略.当然,贪心算法就是动态规划的特例. 算法思想 点对之间的最短路径只会有两种情况: 两点之间有边相连,weight(Vi,Vj)即是最小的. 通过另一点:中介点,两点相连,使weight(Vi,Vk)+weight(Vk,Vj)最小. Min_Distance(Vi,Vj)=min{weight(Vi

【CodeForces - 296D】Greg and Graph(floyd)

Description 题意:给定一个有向图,一共有N个点,给邻接矩阵.依次去掉N个节点,每一次去掉一个节点的同时,将其直接与当前节点相连的边和当前节点连出的边都需要去除,输出N个数,表示去掉当前节点之前的所有两点间最短距离和.n<=500 Solution 如果暴力打肯定是会超时的,那就要运用到floyd(hj) floyd算法内2个循环就相当于新加入外循环的那个点然后跟新最短路, 所以可以把题目看成倒过来依次加点,每次\(n^2\)平方更新一下,总共\(O(n^3)\) Code #incl

(转)Floyd算法

原文地址:http://www.cnblogs.com/twjcnblog/archive/2011/09/07/2170306.html 参考资料:http://developer.51cto.com/art/201403/433874.htm 正如我们所知道的,Floyd算法用于求最短路径.Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3). Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接

多源最短路径Floyd算法

多源最短路径是求图中任意两点间的最短路,采用动态规划算法,也称为Floyd算法.将顶点编号为0,1,2...n-1首先定义dis[i][j][k]为顶点 i 到 j 的最短路径,且这条路径只经过最大编号不超过k的顶点.于是我们最终要求的是dis[i][j][n-1].状态转移方程如下: dis[i][j][k]=min{dis[i][j][k-1],dis[i][k][k-1]+dis[k][j][k-1]}; 状态转移方程的解释:在计算dis[i][j][k]的时候,我们考虑 i 到 j 是否

hdu 1599 find the mincost route (最小环与floyd算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1599 find the mincost route Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2530    Accepted Submission(s): 1006 Problem Description 杭州有N个景区,景区之间有一

Floyd算法的原理和实现

一.算法介绍 Floyd算法是一种在有向图中求最短路径的算法.相比不能再有向图中包含负权值的dijkstra算法,Floyd算法可以用在拥有负权值的有向图中求解最短路径(不过不能包含负权回路).它是一种求解有向图中点与点之间最短路径的算法. 我们检查有向图中的每一个节点X,对于图中过的2点A和B,如果有Dis(AX)+Dis(XB)<Dis(AB),那么使得Dis(AB)=Dis(AX)+Dis(XB).当所有的节点X遍历完后,AB的最短路径就求出来了. 所以,核心代码很简单,其中N是顶点个数,

Floyd算法(二)之 C++详解

本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想