香甜的黄油

香甜的黄油

题目描述

农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1≤N≤500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。

农夫John很狡猾。像以前的巴甫洛夫,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。

农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。
在这里插入图片描述
输入样例:
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5

输出: 8

思路:也就是求最短路径,即求解所有奶牛所在牧区距离放糖的牧区之间的距离之和最短。
这边不能采用传统的求解最短路径的算法。我们采用SPFA算法(Shortest Path Faster Algorithm)

SPFA算法详解

参考博客:https://blog.csdn.net/muxidreamtohit/article/details/7894298

适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了。 我们约定有向加权图G不存在负权回路,即最短路径一定存在。当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点。

算法思想:我们用数组d记录每个结点的最短路径估计值,用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止

期望的时间复杂度O(ke), 其中k为所有顶点进队的平均次数,可以证明k一般小于等于2。

实现方法:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int G[801][801], hd[100000], tot, d[100010];
// d[i]代表i奶牛在哪个牧区 
struct node{
	int x, y, next, w;
}a[100010];		// 边结构 

int v[100010];
int p[100010];	// 定义队列 
// 邻接表 
void add(int x, int y, int z){	
	tot++;
	a[tot].x = x;	// 边头结点 
	a[tot].y = y;	// 边尾结点 
	a[tot].w = z;	// 边的权值 
	a[tot].next = hd[x]; 	// 指向上一条边(具有相同的头结点) 
	hd[x] = tot;	// 统计以x为头结点的边数 
	// cout << "a["<< tot << "].next:" << a[tot].next << endl; 
}

void spfa(int x){
	memset(v, 0, sizeof(v));	// 标记顶点是否在队列中 
	G[x][x] = 0;
	queue<int> p;	// 创建列表
	p.push(x);		// 源点进入列表
	v[x] = 1; 
	while(!p.empty()){	// 判断列表是否为空 
		int x1 = p.front(); 
		p.pop();	// 出队列 
		v[x1] = 0; 
		for(int j=hd[x1];j; j=a[j].next){
			if(G[x][a[j].y]>G[x][x1]+a[j].w){
				G[x][a[j].y] = G[x][x1]+a[j].w;		// 松弛操作
				if(v[a[j].y] == 0){
					// v[x1] = 1;
					p.push(a[j].y);				// 刷新成功且被刷新点不在队列中则把该点加入到队列最后
					v[a[j].y] = 1;
				} 
			}
		}
	} 
}

int main(){
	memset(G, 100, sizeof(G));	//将G的空间赋值为100
	//奶牛数N,牧场数P(2≤P≤800),牧场间道路数C(1≤C≤1450)。
	int n, p, c;
	cin >> n >> p >>c;
	//奶牛的存储位置
	for(int i=1; i<=n; i++){
		cin >> d[i];
	} 
	// 输入牧场间的通道
	for(int i=1; i<=c; i++){
		int x, y, z;
		cin >> x >> y >> z;
		add(x, y, z);
		add(y, x, z);
	}
	
	for(int i=1; i<=p; i++){
		spfa(i);
	}
	
	int min_dis = 100000000;
	for(int i=1; i<=p; i++){
		int ans = 0;
		for(int j=1; j<=n; j++){
			ans += G[d[j]][i];
		}
		min_dis = min(min_dis, ans);
	}
	cout << min_dis;
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黄油刀(ButterKnife)是一款Android视图的字段和方法绑定快速注解框架。它是由JakeWharton开发的,可以帮助Android开发者简化代码,省去繁琐的findViewById操作。 使用黄油刀可以在代码中使用注解的方式来绑定视图,避免了手动查找和绑定视图的过程,提高了开发效率。在使用黄油刀前,需要在build.gradle文件中添加依赖: implementation 'com.jakewharton:butterknife:10.2.3'// 添加此依赖 annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'// 添加此规则 然后,在需要使用黄油刀的Activity或Fragment中,可以通过注解的方式绑定视图。黄油刀使用的注解并不是在运行时反射的,而是在编译时生成新的class,所以对性能基本没有损失。 总的来说,黄油刀是一个方便易用的Android视图绑定框架,可以帮助开发者简化代码,提高开发效率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Android Butterknife(黄油刀) 使用方法总结](https://blog.csdn.net/donkor_/article/details/77879630)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Android(ButterKnife)黄油刀使用详解](https://blog.csdn.net/ojbk99267710/article/details/126098708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值