AcWing 3305. 作物杂交
创始人
2024-05-30 19:22:11
0

 

先看看题目,总结下来就是根据已有的种子进行杂交,以最快的速度得到目标种子。

这个题是蓝桥杯的原题,在蓝桥杯练习系统提交的时候,用dfs是可以过的,但是在acwing上是过不了的,好像是因为会出现环。

所以在这里把两种思路都记下来。

1.dfs

dfs的思路比较简单,查找可以杂交得到目标种子的植物a和b,如果a和b没有现成的种子,那么接着查找a和b通过杂交得到的最短时间。

这个思路很简单的,所以也没啥可说的。然后一个需要注意的点是dfs返回的是得到该种子的时间,所以杂交的时候得等到这个种子长成植物之后才可以。

那么我们在计算通过种子a和b得到c的时间就是seed[a] = max(seed[b],seed[c])+max(t[a],t[b]).先同时得到a和b的种子,然后同时种下去。

代码如下:

int T[N];
int K[N];
int flag[N];  //是否得到了这个种子 
int seed[N];  //得到每个种子的最小时间 
vectormp[N];
int dfs(int x){for(int i = 0; i < mp[x].size(); i += 2){int a = mp[x][i];int b = mp[x][i + 1];if(!flag[a]) seed[a] = dfs(a);if(!flag[b]) seed[b] = dfs(b);seed[x] = min(seed[x], max(seed[a], seed[b]) + max(T[a], T[b]));flag[x] = 1;} return seed[x];
} 
int main(){int n, m, k, t;cin>>n>>m>>k>>t;memset(seed, 0x3f, sizeof(seed));for(int i = 1; i <= n; i++){cin>>T[i];} for(int i = 0; i < m; i++){cin>>K[i];flag[K[i]] = 1;seed[K[i]] = 0; }for(int i = 0; i < k; i++){int a, b, c;cin>>a>>b>>c;mp[c].push_back(a);mp[c].push_back(b);}cout<

2.spfa

说实话,如果这道题的算法标签不打上spfa的话,我是肯定想不到的。但是即使打上了,我也还是没明白怎么建图。

下面记录一下我的草率理解。

图中有n个顶点,有m条边,我们在使用邻接表建图的时候,这条边上不但可以存储边权,也可以存储其他的信息,例如这条边相关的两个节点可以生成的新种子。那么我们在建边的时候不但要记录这条边的两个顶点还要记录这两个种子杂交生成的新种子。

然后这个题我是这么理解的,因为我们想要得到生成目标种子的最短时间,相当于走了很多条边然后得到一条到目标种子t的最短路。

但是这个spfa是计算的单源路径的,这个源在哪呢?于是我们想到了前几天做的那道题,我们也虚拟一个超级源点,然后对于每个已有的种子,和这个超级源点0之间的距离就是0。然后我们对现有的边开始枚举,不断更新每个顶点到源点的距离,直到我们得到目标种子的最短时间,也就是和源点之间的最短路径。

然后代码如下:

#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int N = 2010;
const int M = 200005;
int h[N], e[M], ne[M], target[M], idx, w[N];
int dis[N]; 
bool st[N];
int n, m, k, t; 
queueq;
void add(int a, int b, int c){e[idx] = b;target[idx] = c;  //可以杂交生成的种子ne[idx] = h[a];h[a] = idx++;
} 
void spfa(){while(q.size()){int x = q.front();q.pop();st[x] = false;  //出队就标记for(int i = h[x]; i != -1; i = ne[i]){int y = e[i];int z = target[i];if(dis[z] > max(dis[x], dis[y]) + max(w[x], w[y])){  //用这两个顶点来更新边上的顶点zdis[z] = max(dis[x], dis[y]) + max(w[x], w[y]);if(!st[z]){q.push(z);st[z] = 1;  //入队}}} }
}
int main(){scanf("%d%d%d%d", &n, &m, &k, &t);memset(dis, 0x3f, sizeof(dis));memset(h, -1, sizeof(h));for(int i = 1; i <= n; i++) scanf("%d", &w[i]);for(int i = 1; i <= m; i++){int x;scanf("%d", &x);dis[x] = 0;  //现有的种子,最短路径为0q.push(x);st[x] = true;   //如入队了}for(int i = 1; i <= k; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);add(b, a, c);} spfa();printf("%d\n", dis[t]);return 0;
} 

我是真的不懂spfa是什么。先写到这,我饿了。

最近睡得不好,心脏都不好。我明天开始就好好养生,好好学习!!!

相关内容

热门资讯

洛克王国不倒叮当 洛克王国不倒叮当好不容易抓个好点的。。性格是保守的。。郁闷了一般稀有宠物的天赋都很高,不到叮当,还不...
不是善茬歇后语下一句 不是善茬歇后语下一句张飞胡敬德剃了胡子——都也不是善茬张飞胡敬德剃胡子一都不是善茬都不是善茬,谁也不...
《有钱没钱回家过年》到底是谁唱... 《有钱没钱回家过年》到底是谁唱的?怎么有好多个版本?请大家帮忙找一下关于这首歌的详细介绍,最近好像流...
傲视天地 里外城的精炼该怎么弄... 傲视天地 里外城的精炼该怎么弄?楼上正解。。没啥可补充了。。。是个很靠谱的提升石头产出的东西亲爱的玩...
《安徒生童话》中有哪个故事中的... 《安徒生童话》中有哪个故事中的主人公最奇怪《安徒生童话》中,**依达**是最奇怪的角色。《小猪倌》。...
悲莫悲兮生别离,乐莫乐兮新相知... 悲莫悲兮生别离,乐莫乐兮新相知啥意思在悲伤啊莫过于活生生的别离,再快乐啊莫过于新相交的知己。
听的多音字是什么 听的多音字是什么听拼音tīng释义1.用耳朵接受声音:~力。~写。~觉。聆~。洗耳恭~。2.顺从,接...
★求最终幻想13男女主角的名字... ★求最终幻想13男女主角的名字!男主很高很帅,戴一个黑色帽子,黄头发;女主很小巧可爱,头发歪着梳的男...
泡沫之夏小说中的洛熙花心吗 泡沫之夏小说中的洛熙花心吗洛熙很专一很痴情很专一很痴情
翻身乐队免费的吗 翻身乐队免费的吗免费。翻身乐队是深圳的一个乐队,一群喜欢音乐的人相约深圳,每周在路边免费路演。
求小说 男女主高中相爱 男主车... 求小说 男女主高中相爱 男主车祸失忆 女主生了个宝宝 男主姓盛 后来男主受伤了 被女主救了求小说 男...
男生是不是都喜欢比较柔弱的女生... 男生是不是都喜欢比较柔弱的女生?柔弱的女生可以激发男生的保护欲,男生一般特别爱表现自己,特别是展现他...
相比其他作品,为什么没有人翻拍... 相比其他作品,为什么没有人翻拍金庸的《连城诀》?因为书中确实很现实,大多数人不喜欢接受现实,都是带着...
“存”繁体字怎么写? “存”繁体字怎么写?”存“字的繁体字即为简体写法”存“,读音”cún“。
三人成虎的意思 三人成虎的意思三人成虎的意思是:有三个人谎报市上有虎,听者就信以为真。比喻讹传一再重复,就可能以假充...
为什么男孩子总是欺骗女孩子? 为什么男孩子总是欺骗女孩子?不管是善意还是恶意的,难道欺骗是你们的爱好吗? 难道这样女孩子就是你的了...
活着的歌词 活着的歌词 《活着》 演唱:郝云 词曲:郝云每天站在高楼上看着地上的小蚂蚁它们的头很大它们的...
给侄女起名字 给侄女起名字大家好,我哥叫叶三杰,嫂子叫赵娟,嫂子在正月初5下午13点给偶家添一千金,想起个名。谢谢...
孔雀东南飞,到底是什么意思,有... 孔雀东南飞,到底是什么意思,有什么寓意?不能棒打鸳鸯呀《孔雀东南飞》是一个爱情故事,原文是表达两人的...
齐秦的女儿,儿子 齐秦的女儿,儿子做到不抱怨 最重要的一条 就是不要在乎 你都不放在心上!就不会在乎...