【题目链接】

ybt 1345:【例4-6】香甜的黄油
洛谷 P1828 [USACO3.2]香甜的黄油 Sweet Butter

【题目考点】

1. 图论 最短路径

【解题思路】

将题目叙述转为图论概念,牧场为顶点,牧场间的路线为边。该题一个顶点上有多头牛,这个后面再考虑。
记有V个顶点,E条边,有n头牛,每头牛所在顶点为v1,v2,...vnv_1,v_2,...v_nv1​,v2​,...vn​,d(i,j)d(i,j)d(i,j)为顶点i,j间的最短路径长度。
题目要问的问题是,选择一个顶点c,使得∑i=1nd(vi,c)\sum_{i=1}^nd(v_i,c)∑i=1n​d(vi​,c)最小。
如果已知每头牛所在顶点到其它任意顶点的最短路径长度,那么接下来就可以遍历所有顶点,记遍历到的顶点为i,选择顶点i为放糖的地方,求所有牛所在顶点到顶点i的最短路径加和,这一步的复杂度为O(V⋅n)O(V\cdot n)O(V⋅n)
问题落在如何求每头牛所在顶点到其它任意顶点的最短路径。

  • 使用Floyd算法,求所有顶点间的最短路径长度。题目给定顶点数(牧场数)最大为800,Floyd算法的复杂度为O(V3)O(V^3)O(V3),8003=5.12∗108800^3=5.12*10^88003=5.12∗108,运算次数在10710^7107以下可以保证不会超时,复杂度达到10810^8108数量级很可能会超时,所以不能用Floyd算法。
    如果用单源最短路径算法,需要对每头牛所在顶点跑一次单源最短路径算法。算法整体复杂度为:O(n)O(n)O(n)乘以所用的单源最短路径算法的复杂度。
  • 考虑使用朴素Dijkstra算法,整体复杂度为O(n⋅V2)O(n\cdot V^2)O(n⋅V2),计算500∗8002=3.2∗108500*800^2=3.2*10^8500∗8002=3.2∗108,不可行。
  • 使用Dijkstra堆优化算法,整体复杂度为O(n⋅ElogE)O(n\cdot ElogE)O(n⋅ElogE),题目中边数最多约为1500,计算500∗1500∗log21500≈8.25∗106500*1500*log_21500\approx8.25*10^6500∗1500∗log2​1500≈8.25∗106,可行。
  • 使用SPFA算法,复杂度为O(kE)O(kE)O(kE),k为每个顶点平均入队次数,在稀疏图中一般小于2,可以认为等于2。用SPFA算法做该问题,整体复杂度为O(n⋅kE)O(n\cdot kE)O(n⋅kE),计算500∗2∗1500=1.5∗106500*2*1500 = 1.5*10^6500∗2∗1500=1.5∗106,可行。

以上是思考过程,该题做法为:

  1. 通过Dijkstra堆优化算法或SPFA算法求出每个牛所在顶点到其它所有顶点的最短路径
  2. 遍历每个顶点v,求每个牛所在顶点到v的最短路径长度乘以那里牛的数量,再加和。求这些加和中的最小值。

【题解代码】

解法1:Dijkstra堆优化算法

#include<bits/stdc++.h>
using namespace std;
#define N 805
#define INF 0x3f3f3f3f
struct Pair
{int v, d;Pair(){}Pair(int a, int b):v(a),d(b){}bool operator < (const Pair &b) const{return b.d < d;}
};
struct Edge
{int t, w;Edge(){}Edge(int a, int b):t(a),w(b){}
};
int n, p, c;
bool vis[N];
int dis[N][N];//dis[i][j]:i到j的最短路径长度
int place[N];//place[i]:牛i所在的顶点
vector<Edge> edge[N];
void initGraph()
{int f, t, w;cin >> n >> p >> c;for(int i = 1; i <= n; ++i)cin >> place[i];for(int i = 1; i <= c; ++i){cin >> f >> t >> w;edge[f].push_back(Edge(t, w));edge[t].push_back(Edge(f, w));}
}
void dijkstra(int v0)
{memset(vis, 0, sizeof(vis));priority_queue<Pair> pq;dis[v0][v0] = 0;pq.push(Pair(v0, 0));while(pq.empty() == false){int u = pq.top().v;pq.pop();if(vis[u])continue;vis[u] = true;for(int i = 0; i < edge[u].size(); ++i){int v = edge[u][i].t, w = edge[u][i].w;if(vis[v] == false && dis[v0][v] > dis[v0][u] + w){dis[v0][v] = dis[v0][u] + w;pq.push(Pair(v, dis[v0][v]));}}}
}
int main()
{int v0, sum, ans = INF;initGraph();memset(dis, 0x3f, sizeof(dis));for(int i = 1; i <= n; ++i){v0 = place[i];//起点 if(dis[v0][v0] == INF)//如果该顶点的单源最短路径问题没有求过了 dijkstra(v0);}for(int i = 1; i <= p; ++i){//在顶点i放糖 sum = 0;for(int j = 1; j <= n; ++j)sum += dis[place[j]][i];ans = min(ans, sum);}cout << ans;return 0;
}

解法2:SPFA算法

#include<bits/stdc++.h>
using namespace std;
#define N 805
#define INF 0x3f3f3f3f
struct Pair
{int v, d;Pair(){}Pair(int a, int b):v(a),d(b){}bool operator < (const Pair &b) const{return b.d < d;}
};
struct Edge
{int t, w;Edge(){}Edge(int a, int b):t(a),w(b){}
};
int n, p, c;
bool vis[N];
int dis[N][N];//dis[i][j]:i到j的最短路径长度
int place[N];//place[i]:牛i所在的顶点
vector<Edge> edge[N];
void initGraph()
{int f, t, w;cin >> n >> p >> c;for(int i = 1; i <= n; ++i)cin >> place[i];for(int i = 1; i <= c; ++i){cin >> f >> t >> w;edge[f].push_back(Edge(t, w));edge[t].push_back(Edge(f, w));}
}
void spfa(int v0)
{memset(vis, 0, sizeof(vis));queue<int> que;dis[v0][v0] = 0;que.push(v0);vis[v0] = true;while(que.empty() == false){int u = que.front();que.pop();vis[u] = false;for(int i = 0; i < edge[u].size(); ++i){int v = edge[u][i].t, w = edge[u][i].w;if(dis[v0][v] > dis[v0][u] + w){dis[v0][v] = dis[v0][u] + w;if(vis[v] == false){que.push(v);vis[v] = true;}}}}
}
int main()
{int v0, sum, ans = INF;initGraph();memset(dis, 0x3f, sizeof(dis));for(int i = 1; i <= n; ++i){v0 = place[i];//起点 if(dis[v0][v0] == INF)//如果该顶点的单源最短路径问题没有求过了 spfa(v0);}for(int i = 1; i <= p; ++i){//在顶点i放糖 sum = 0;for(int j = 1; j <= n; ++j)sum += dis[place[j]][i];ans = min(ans, sum);}cout << ans;return 0;
}

信息学奥赛一本通 1345:【例4-6】香甜的黄油 | 洛谷 P1828 [USACO3.2]香甜的黄油 Sweet Butter相关推荐

  1. 【例1】 0/1背包《信息学奥赛一本通》【解法一】 02

    /* [例1] 0/1背包<信息学奥赛一本通>[解法一] 02 http://ybt.ssoier.cn:8088/problem_show.php?pid=1267 */ #includ ...

  2. 【例8】合唱队形(《信息学奥赛一本通第五版》)

    /* [例8]合唱队形(<信息学奥赛一本通第五版>) http://ybt.ssoier.cn:8088/problem_show.php?pid=1264 [问题描述] N位同学站成一排 ...

  3. 信息学奥赛一本通 2021:【例4.6】最大公约数

    [题目链接] ybt 2021:[例4.6]最大公约数 [题目考点] 1. while循环 2. 求最大公约数 辗转相减法 辗转相除法 [解题思路] 解法1:枚举 取较小数字,从该数字的值开始从大到小 ...

  4. 信息学奥赛一本通(2032:【例4.18】分解质因数)

    2032:[例4.18]分解质因数 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 582     通过数: 376 [题目描述] 把一个合数分解成若干个质因数乘积 ...

  5. 信息学奥赛一本通——2062:【例1.3】电影票

    2062:[例1.3]电影票 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 57341     通过数: 34230 [题目描述] 已知一位小朋友的电影票价是10 ...

  6. 信息学奥赛一本通 1278:【例9.22】复制书稿(book) | 洛谷 P1281 书的复制

    [题目链接] ybt 1278:[例9.22]复制书稿(book) 洛谷 P1281 书的复制 [题目考点] 1. 动态规划:线性动规 [解题思路] 该题可以抽象为:将由m个数字构成的序列分成k个子段 ...

  7. 信息学奥赛一本通1267:【例9.11】01背包问题(二维dp与滚动数组优化)

    [题目描述] 一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,. ...

  8. 信息学奥赛一本通C++语言-----2036:【例5.3】开关门

    [题目描述] 宾馆里有n(2≤n≤1000)n(2≤n≤1000) 个房间,从1∼n1∼n 编了号.第一个服务员把所有的房间门都打开了,第二个服务员把所有编号是22 的倍数的房间"相反处理& ...

  9. 信息学奥赛一本通——2068:【例2.6】鸡兔同笼

    大家好(๑╹◡╹)ノ" 这里是小蒟蒻 一天没更新了呢! 今天给大家带来<信息学奥赛一本通--2068:[例2.6]鸡兔同笼> 题目: 2068:[例2.6]鸡兔同笼 时间限制: ...

最新文章

  1. 人工智能六十年技术简史
  2. python字典增加和删除_Python字典的基本用法实例分析【创建、增加、获取、修改、删除】...
  3. ajax results,jQuery Ajax results in undefined
  4. Oracle数据库中的违规策略规则的修正
  5. Bootstrp--一个导航面板切换的实用例子
  6. 2.Cocos2d-x-3.2编写3d打飞机,项目代码总结
  7. moviepy报错之 .This error can be due to the fact that ImageMagick is not installed on your computer(亲测)
  8. 精美jQuery插件及源码 前端开发福利
  9. (王道408考研操作系统)第三章内存管理-第一节6-2:非连续分配管理方式之基本分页存储管理之基本地址变换机构
  10. HBase数据读取流程解析
  11. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
  12. Spring Boot + Log4j2 日志框架配置 (Maven)
  13. python载入图像
  14. 灰常好的开源项目[c/c++]
  15. zemax光学设计高阶优化
  16. etal斜体吗 参考文献_论文参考文献格式要求
  17. unity获取电磁笔压感_电磁笔的分类和特性
  18. C# 使用正则表达式提取文字
  19. 获取sku详细信息 API 返回值说明
  20. 近期整活之相关软件之安装说明

热门文章

  1. maven的系统变量设置
  2. jquery插件制作 -- 3.表单验证
  3. 基本类型--枚举类型和位标志
  4. 为什么大厂都在造车?原因找到了
  5. 当强人工智能时代来临,哪些人不会失业?
  6. hibernate oracle查询最大值_Java大数据:Mybatis和Hibernate对比分析
  7. pythonmail添加附件_Python 发送邮件可以添加附件
  8. 被裁半年后进大厂,他咋做到的?
  9. 不扯概念,用例子演示什么是脏读,不可重复读,幻读?
  10. 总结一些生物成像的 开源图像与插件网站