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); }
求从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; }
浙公网安备 33010602011771号