Codeforces Beta Round #25 (Div. 2 Only) C. Roads in Berland(Floyd变形)

 

题目大意

 

给了一个 n(2<=n<=300) 个节点的无向图,告诉了每两个节点之间的最短距离,现在要新建 K(1<=K<=300) 条边

要求:每建一条边,输出任意两个点之间最短的距离的和

 

做法分析

 

首先,如果直接暴力的话肯定 T(因为是 o(n4) 的时间复杂度)

我们需要注意的是,每次只是新建一条边

令 g[i][j] 表示顶点 i 和顶点 j 之间的最短距离

假设新建的边是 a---b 边权为 c

 

如果 g[a][b]<=c 那么,新建的边不会用来更新多有顶点之间的最短距离,这时候直接统计最短距离和输出就行,下面讨论 g[a][b]>c 的情况

 

        首先 g[a][b]=g[b][a]=c 这是肯定的了

        由于只是新加了边,原来图中的边还存在(虽然我们不知道这些边的具体情况),那么我们可以这么做,还是利用 Floyd 算法的思想

 

        先求出 a 到其他所有点的最短距离 g[i][a] (由于 g[a][i]=g[i][a],我们只讨论一种情况)

                g[i][a] 要么不经过 a---b 这条边,要么经过这条边,于是很好解决了:

                        g[i][a]=g[a][i]=min( g[i][a], g[i][b]+g[b][a] )

 

        同理,求出 b 到其他所有的点的最短距离:

                        g[i][b]=g[b][i]=min( g[i][b], g[i][a]+g[a][b] )

 

        最后,对于任意两个点 i 和 j,他们的最短路,要么经过 a,要么经过 b,要么还是原来的值,那么

                        g[i][j]=min(g[i][j], min(g[i][a]+g[a][j], g[i][b]+g[b][j]) )

 

这样,任意两个点之间的最短路就求出来了,然后暴力统计就行了

 

参考代码

 

C. Roads in Berland
 1 #include <cstring>
 2 #include <cstdio>
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 const int N=3006;
 8 long long g[N][N];
 9 int n, m;
10 
11 int main()
12 {
13     scanf("%d", &n);
14     for(int i=1; i<=n; i++)
15         for(int j=1; j<=n; j++)
16             scanf("%I64d", &g[i][j]);
17     scanf("%d", &m);
18     for(int e=0, a, b, c; e<m; e++)
19     {
20         scanf("%d%d%d", &a, &b, &c);
21         if(g[a][b]>c)
22         {
23             g[a][b]=g[b][a]=c;
24 
25             for(int k=1; k<=n; k++)
26                 for(int i=1; i<=n; i++)
27                     g[i][a]=g[a][i]=min(g[a][i], g[a][b]+g[b][i]);
28             for(int k=1; k<=n; k++)
29                 for(int i=1; i<=n; i++)
30                     g[i][b]=g[b][i]=min(g[b][i], g[b][a]+g[a][i]);
31             for(int i=1; i<=n; i++)
32                 for(int j=i+1; j<=n; j++)
33                 {
34                     g[i][j]=g[j][i]=min(g[i][j], g[i][a]+g[a][j]);
35                     g[i][j]=g[j][i]=min(g[i][j], g[i][b]+g[b][j]);
36                 }
37         }
38         long long sum=0;
39         for(int i=1; i<=n; i++)
40             for(int j=i+1; j<=n; j++)
41                 sum+=g[i][j];
42         printf("%I64d\n", sum);
43     }
44 }

 

题目链接 & AC通道

 

Codeforces Beta Round #25 (Div. 2 Only) C. Roads in Berland

 

 

 

转载于:https://www.cnblogs.com/zhj5chengfeng/archive/2013/04/21/3034292.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值