作物杂交(bellman-ford和spfa)
二者的思路是一样的,spfa是bellman-ford的优化
bellman-ford
//bellman_ford
//直接写会TLE,如何优化?——当我们发现在某一层迭代中没有一个d更新的话,就可以break了,因为只有当某个点的前驱节点更新了,该节点才会更新
#include<bits/stdc++.h>
using namespace std;
#define N 2010
#define M 100010
struct Edge
{
int a,b,c;//由a,b点可以生成c点
};
Edge p[M];
int n,m,k,t,w[N];//w:成熟时间
bool hav[N];//用于标记已经存在的种子
int d[N];//该号种子出现的时间(它等于它的两个前驱种子出现的时间的较大值+它的两个前驱种子成熟时间的较大值)
void bellman_ford()
{
for(int l=1;l<=n-1;l++)// n号点最多经过n-1次迭代
{
bool st=true;
for(int i=0;i<k;i++)//遍历所有边
{
int a=p[i].a,b=p[i].b,c=p[i].c;
if(hav[a]&&hav[b])
{
if(d[c]>max(d[a],d[b])+max(w[a],w[b]))
{
d[c]=max(d[a],d[b])+max(w[a],w[b]);//(它等于它的两个前驱种子出现的时间的较大值+它的两个前驱种子成熟时间的较大值)
hav[c]=true;//c种子已出现,标记一下
st=false;
}
}
}
if(st) break;//优化
}
}
int main()
{
cin>>n>>m>>k>>t;
memset(d,0x3f,sizeof d);
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=m;i++)//输入存在的种子
{
int x;
cin>>x;
hav[x]=true;
d[x]=0;
}
for(int i=0;i<k;i++)
cin>>p[i].a>>p[i].b>>p[i].c;
bellman_ford();
cout<<d[t]<<endl;
}
作者:less
链接:https://www.acwing.com/solution/content/248530/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
spfa
//spfa
//这次邻接表存的不是每个点所能到达的点和这条边的长度了,而是与某个点关联的点(例如a和b杂交得出c,则a的表里存的是b和c)
#include<bits/stdc++.h>
using namespace std;
#define N 2010
#define M 200010
int e[M],ne[M],h[N],w[N];
int n,m,k,t,idx,d[N],tar[M];//tar:某个种子a和别的种子b杂交得出的种子c,要存两遍(a,b),所以大小要开两倍
bool hav[N];
void add(int l,int r,int c)//l和r杂交得到c点
{
e[idx]=r,ne[idx]=h[l],tar[idx]=c,h[l]=idx++;
}
queue<int> q;
bool st[N];
void spfa()
{
while(q.size())
{
auto a=q.front();
q.pop();
st[a]=false;
for(int i=h[a];i!=-1;i=ne[i])//取出与a(母亲点)有关联的点
{
int b=e[i];//另一个父亲点
int c=tar[i];//孩子点
if(hav[a]&&hav[b])//如果c的前驱种子a和b都存在,就有机会更新c的出现时间
{
if(d[c]>max(d[a],d[b])+max(w[a],w[b]))
{
d[c]=max(d[a],d[b])+max(w[a],w[b]);
if(!st[c]) q.push(c),st[c]=true;
}
hav[c]=true;
}
}
}
}
int main()
{
memset(h,-1,sizeof h);
memset(d,0x3f,sizeof d);
cin>>n>>m>>k>>t;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=m;i++)
{
int x;
cin>>x;
hav[x]=true;
d[x]=0;
q.push(x);
st[x]=true;
}
for(int i=1;i<=k;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
spfa();
cout<<d[t];
}
作者:less
链接:https://www.acwing.com/solution/content/248530/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(思路来自”骄骄是骄傲的骄骄”的题解 )