D62 最短路 Floyd 算法 P1828 [USACO3.2] 香甜的黄油

D62 最短路 Floyd 算法 P1828 [USACO3.2] 香甜的黄油_哔哩哔哩_bilibili

 

P1828 [USACO3.2] 香甜的黄油 Sweet Butter - 洛谷

给了 q 个点,c 条边 的无向图,n 个奶牛放在某些点上,问所有奶牛到哪个点上聚会走的距离和最小。输出距离和最小值。

思路

考虑最短路算法,因为点数 800,边数 1500,所以 Floyd、Dijkstra、spfa 都可以。

如果用 Floyd 算法,就先跑 全源最短路,然后统计距离和,取最小值。

如果用 Dijkstra、spfa 算法,就枚举每个点作为聚会点,跑单源最短路,然后统计距离和,取最小值。

 

三种最短路的板子:

D02 最短路 Dijkstra 算法 P4779【模板】单源最短路径 - 董晓 - 博客园

D03 最短路 Bellman-Ford 算法 spfa 算法 P3385【模板】负环 - 董晓 - 博客园

D04【模板】最短路 Floyd 算法 - 董晓 - 博客园

 

// 最短路 Floyd 算法 O(P^3)
#include<bits/stdc++.h>
using namespace std;

const int N=810;
int n,p,c;
int d[N][N],cnt[N]; 

int main(){
  scanf("%d%d%d",&n,&p,&c); //奶牛数、牧场数、牧场间道路数
  for(int i=1,x;i<=n;i++) scanf("%d",&x),cnt[x]++; //每个点上的牛数
  for(int i=1;i<=p;i++)for(int j=1;j<=p;j++) d[i][j]=(i==j?0:1e9);
  for(int i=1,u,v,w;i<=c;i++) scanf("%d%d%d",&u,&v,&w),d[v][u]=d[u][v]=w;
  
  for(int k=1;k<=p;k++) //Floyd 全源最短路
  for(int i=1;i<=p;i++)
  for(int j=1;j<i;j++)
  if(d[i][j]>d[i][k]+d[k][j]) d[j][i]=d[i][j]=d[i][k]+d[k][j];

  long long ans=1e9;
  for(int i=1;i<=p;i++){ //把糖放在i点
    long long s=0;
    for(int j=1;j<=p;j++) s+=d[i][j]*cnt[j]; //累计距离
    ans=min(ans,s);
  }
  printf("%d",ans);
}

 

T478723 信使 - 洛谷

U167571 信使 - 洛谷

求从1到各点的最短路的最大值。

// 最短路 Floyd 算法 O(n^3)
#include<bits/stdc++.h>
using namespace std;

const int N=110,INF=0x3f3f3f3f;
int n,m;
int d[N][N];

int main(){
  cin>>n>>m;
  memset(d,0x3f,sizeof d);
  for(int i=1;i<=n;i++) d[i][i]=0;
  for(int i=0,a,b,c;i<m;i++){
    cin>>a>>b>>c;
    d[a][b]=d[b][a]=min(d[a][b],c);
  }
  
  for(int k=1;k<=n;k++) //Floyd
  for(int i=1;i<=n;i++)
  for(int j=1;j<=n;j++)
  d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
  
  int res=0;
  for(int i=2;i<=n;i++){
    if(d[1][i]==INF){res=-1; break;}
    else res=max(res,d[1][i]); //1到各点的最短路的最大值
  }
  cout<<res;
}

 

posted @ 2026-02-09 19:06  董晓  阅读(147)  评论(0)    收藏  举报