被这几个板子折磨,打一打最近学的最短路模板
Floyd朴素算法
优点:全能,编程复杂度低
缺点:时空复杂度高,不易优化
#include <bits/stdc++.h> using namespace std; #define map mymap const int p=100+1; int n,m,s,t; int ans; int map[p][p]; int main(){ cin>>n>>m>>s>>t; memset(map,0x3f,sizeof(map)); int x,y; for(int i=1;i<=m;i++){ cin>>x>>y; } for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ map[i][j]=min(map[i][j],map[i][k]+map[k][j]); } } } cout<<map[s][t]; return 0; }
优点:时间复杂度较小,为O(n^2)级(应用数据规模从500到10000),可以被优化,复杂度稳定
缺点:无法处理负边权问题,单源
1.无优化
#include <bits/stdc++.h> using namespace std; int a[101][3]; double c[101]; bool b[101]; double f[101][101]; int n,m,s,t; void in(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i][1],&a[i][2]); } memset(f,127,sizeof(f)); scanf("%d",&m); int x,y; for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); f[x][y]=f[y][x]=sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2)); } scanf("%d%d",&s,&t); } void dij(){ memset(b,0,sizeof(b)); b[s]=1; c[s]=0; for(int i=1;i<=n;i++){ c[i]=f[s][i]; } double minl; for(int i=1;i<n;i++){ minl=1e30; int k=0; for(int j=1;j<=n;j++){ if((!b[j])&&(c[j]<minl)){ minl=c[j]; k=j; } } if(k==0){ break; } b[k]=1; for(int j=1;j<=n;j++){ if(c[k]+f[k][j]<c[j]){ c[j]=c[k]+f[k][j]; } } } } void out(){ printf("%.2lf",c[t]); } int main(){ in(); dij(); out(); return 0; }
3.spfa算法
优点:可解负边权问题,时间复杂度为O(kn),k常数较小,因此快,可优化
缺点:可被特殊构造的数据卡掉退化为O(mn)
啊这,spfa优化很多但都容易被hack掉退化成原形,所以考场少用SPFA
为已死的SPFA默哀
由于蒟蒻啥样的SPFA优化不会并且无优化SPFA都几乎没打过,所以直接贴代码跑路了
#include <bits/stdc++.h> using namespace std; #define map mymap queue<int>q; int n,m,map[2021][2022],dis[2005]; bool vis[2005]; void spfa(){ q.push(1); vis[1]=true; dis[1]=0; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=false; for(int i=1;i<=n;i++){ if(map[x][i]>0&&(min(dis[x],map[x][i])>dis[i]||!dis[x])){ if(!dis[x]){ dis[i]=map[x][i]; } else{ dis[i]=min(dis[x],map[x][i]); } if(!vis[i]){ vis[i]=true; q.push(i); } } } } } int main(){ scanf("%d",&n); memset(map,0,sizeof(map)); for(int i=2;i<=n;i++){ dis[i]=0; } int f,t,p; while(scanf("%d%d%d",&f,&t,&p)==3){ if(!f&&!t&&!p){ break; } else{ map[f][t]=p; } } spfa(); for(int i=2;i<=n;i++){ printf("%d\n",dis[i]); } return 0; }
综上:把堆优化Dijsktra和SPFA打熟是绝对有好处的据说网络流有用,不过蒟蒻fw一个管他网啥