本蒟蒻看楼上一群大佬用STL写SPFA,就想着用普通的SPFA写一篇题解。
看题目也知道,如果只是朴素的FLOYED肯定是会超时的,所以这里考虑使用最快的SPFA算法。
话不多说,上代码~~
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,p,c,i,j,x,y,t,min1,head,tail,tot,u;
inta[801][801],b[501],dis[801],num[801],w[801][801],team[1601];
bool exist[801];
int main()
{
cin>>n>>p>>c;
for(i=1;i<=p;i++)
for(j=1;j<=p;j++)
w[i][j]=0x7fffffff/3;
for(i=1;i<=n;i++)
cin>>b[i];
for(i=1;i<=c;i++) //邻接矩阵存储
{
cin>>x>>y>>t;
w[x][y]=w[y][x]=t; //双向
a[x][++num[x]]=y; //存储于每个牧场相连的牧场序号
a[y][++num[y]]=x;
}
min1=0x7fffffff/3;
for(i=1;i<=p;i++)
{
for(j=1;j<=p;j++) dis[j]=0x7fffffff/3;memset(team,0,sizeof(team)); //队列数组初始化memset(exist,false,sizeof(exist)); //标记数组初始化
dis[i]=0;team[1]=i;head=0;tail=1;exist[i]=true; //起始点入队
do
{
head++;
head=((head-1)%1601)+1; //循环队列,有效节约空间
u=team[head];
exist[u]=false;
for(j=1;j<=num[u];j++)//循环判断每一个与头相连的点
if(dis[a[u][j]]>dis[u]+w[u][a[u][j]])
{
dis[a[u][j]]=dis[u]+w[u][a[u][j]];
if(!exist[a[u][j]]) //入队操作
{
tail++;
tail=((tail-1)%1601)+1;
team[tail]=a[u][j];
exist[a[u][j]]=true;
}
}
}while(head!=tail);
tot=0;
for(j=1;j<=n;j++)
tot+=dis[b[j]];
if(tot<min1) min1=tot;
}
cout<<min1;
return 0;
}
近期评论