zoukankan      html  css  js  c++  java
  • 【codevs2011】最小距离之和 [LNOI2013](Floyd)

    题目网址:http://codevs.cn/problem/2011/

    题目大意:有一个图,每次删一条边(可以重复删),求每次删边之后所有点对的最短距离之和。

      看了一眼题目,顿时发现了O(n^4)的暴力解法:每次删边之后跑一次Floyd,然后又看了一眼数据范围,发现n,m<=200……华丽丽的TLE……

      删边……好像不可做……但是如果是加边就好办了。看看能不能把删边转化成加边,于是……正解思路闪现了。

      其实这道题的思路就是把要删掉的边全部先删掉,跑一次Floyd,然后倒着加边,用加上的边更新最短路(设加上的边起点为x,终点为y,看i->x->y->j是否比直接i->j花费更小),就能在O(n^3)的时间内求出答案。

      代码:

    var a:array[0..210,0..210]of longint;
      x,y,z,ans:array[0..210]of longint;
      n,m,i,j,k:longint;
      b:boolean;
    begin
      read(n);
      for i:=1 to n do
        for j:=1 to n do
          read(a[i,j]);//读入图
      read(m);
      for i:=1 to m do begin
        read(x[i],y[i]); z[i]:=a[x[i],y[i]];
        a[x[i],y[i]]:=1<<29;//删边
      end;
      for k:=1 to n do
        for i:=1 to n do
          for j:=1 to n do
            if a[i,j]>a[i,k]+a[k,j] then a[i,j]:=a[i,k]+a[k,j];//跑Floyd
      for i:=m downto 1 do begin
        ans[i]:=0; b:=false;
        for j:=1 to n do begin
          for k:=1 to n do begin
            if a[j,k]>=1<<29 then begin
              ans[i]:=-1; b:=true; break;
            end;
            ans[i]:=ans[i]+a[j,k];
          end;
          if b then break;
        end;//算距离之和
        for j:=1 to n do
          for k:=1 to n do
            if a[j,k]>a[j,x[i]]+z[i]+a[y[i],k] then a[j,k]:=a[j,x[i]]+z[i]+a[y[i],k];//加边,更新答案
      end;
      for i:=1 to m do
        if ans[i]=-1 then writeln('INF')
        else writeln(ans[i]);//输出答案
    end.
    View Code

    注:更新答案时不能用删掉的边直接覆盖掉原边,因为覆盖掉的花费可能更短。

  • 相关阅读:
    IE下PNG透明图片fadeIn出现黑边的问题
    愿闻其翔记(一)
    简单的日期选择器
    HTML5 贪吃蛇
    HTML5小程序,变化的色彩
    HTML5 Canvas 基本图形画法
    帝国CMS实现一二级导航及其高亮
    php中json_decode()和json_encode()
    JavaScript重复元素处理
    JQuery在光标位置插入内容
  • 原文地址:https://www.cnblogs.com/quzhizhou/p/6378621.html
Copyright © 2011-2022 走看看