最短路
1 //弗洛伊德 floyd 2 void floyd()// n3 3 { 4 //想象为在拉面条,不断进行松弛操作 5 for(ll k=1;k<=n;++k)//k必须放在最外层 6 for(ll i=1;i<=n;++i)//枚举两端点 7 for(ll j=1;j<=n;++j) 8 g[i][j]=min(g[i][j],g[i][k]+g[k][j]); 9 } 10 //迪杰斯特拉 dijkstra 11 //本质为贪心,即每次取距离最短的点,不断进行松弛操作 12 //时间复杂度:未加堆优化时是n^2,加了堆优化后是nlogn 13 //稳定性很强,但是仅适用于正边权,有负边权就game over了 14 ll dis[N],head[M]; 15 bool vis[N]; 16 struct node 17 { 18 ll len,poi; 19 friend bool operator < (node a,node b) 20 { 21 return a.len>b.len; 22 } 23 } 24 struct edge 25 { 26 ll nex,to,lenth; 27 }e[M]; 28 void dijkstra()//堆优化 29 { 30 dis[start]=0; 31 q.push((node){0,start}); 32 while(!q.empty()) 33 { 34 node u=q.top();q.pop(); 35 l x=u.poi,d=u.dis; 36 if(vis[x])continue; 37 vis[x]=1; 38 for(ll i=head[x];i;i=e[i].nex) 39 { 40 ll v=e[i].to,l=e[i].lenth; 41 if(v==u)continue; 42 if(dis[v]>dis[u]+lenth) 43 { 44 dis[v]=dis[u]+lenth; 45 if(vis[v])continue; 46 q.push((node){dis[v],v}); 47 } 48 } 49 } 50 } 51 // spfa 52 // 动态逼近法,也是不断松弛,能够判断负环,即一个点入队次数超过n次 53 // 可以用于负边权 54 queue<ll>q; 55 void spfa()//该代码没判断负环哦 56 { 57 q.push(start);dis[start]=0;vis[start]=1; 58 while(!q.empty()) 59 { 60 ll u=q.front();q.pop();vis[u]=0; 61 for(ll i=head[u];i;i=e[i].nex) 62 { 63 ll v=e[i].to,l=e[i].len; 64 if(dis[v]>dis[u]+l) 65 { 66 dis[v]=dis[u]+l; 67 if(vis[v]==0) 68 { 69 q.push(v);vis[v]=1; 70 } 71 } 72 } 73 } 74 } 75 // dijkstra和spfa其实是很像的 76 // 稠密图:dijstra+堆优化 更好 77 // 稀疏图:spfa 更好 78 // 建议用dijkstra,spfa自从在NOI2018被卡后都不敢用了