最短路算法(dijkstra,bellman_ford,floyd)
最短路算法
dijkstra(初级的最短路算法,适合稠密图,可用邻接表优化)
bool relax(int u,int v) { double tmp=max(dist[u],edge[u][v]); if(tmp<dist[v]){ dist[v]=tmp; } } void dijkstra() { memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ int x; double mindist=INF; for(int j=0;j<n;j++){ if(vis[j]) continue; if(dist[j]<mindist) mindist=dist[x=j]; } vis[x]=1; for(int v=0;v<n;v++){ if(v==x) continue; relax(x,v); } } }
bellman_ford(实用高效的最短路算法,实际复杂度远小于最坏复杂度o(NM),可判断负环)
bool bellman_ford() //bool 判断是否有负环 { for(int i=0;i<n;i++) dist[i]=(i==s)0:INF; for(int i=0;i<n-1;i++){ //松弛n-1次,实际小于n-1次 bool flag=0; //此变量判断能否继续松弛,若不能退出算法 for(int j=0;j<e;j++){ if(relax(j)) flag=1; } if(dist[s]<0) return true; if(!flag) return false; } for(int i=0;i<e;i++){ //此处检查负环,如果松弛了n-1次还能继续松弛说明有负环 if(relax(i)) return true; } return false; }
int bellman_ford() { for(int i=0;i<n;i++) dist[i]=(i==s)0:INF; for(int i=0;i<n-1;i++){ bool flag=0; for(int j=0;j<e;j++){ if(relax(j)) flag=1; } if(!flag) break; } return dist[s]; }
floyd(适合求任意两点的最短路或传递闭包判断拓扑序列,时间复杂度较高)
void floyd() { for(int k=1;k<=n;k++){ for(int u=1;u<=n;u++){ for(int v=1;v<=n;v++){ if(edge[u][v]<edge[u][k]+edge[k][v]) edge[u][v]=edge[u][k]+edge[k][v]; } } } } /* 传递闭包:将循环内改成这样即可: if(G[u][k]&&G[k][v]) G[u][v]=1; */
除此之外求最短路还有SPFA,A*等算法,以后再慢慢学------
===================================================================================================
补充,SPFA算法
int N,M,S,T; bool vis[maxn]; ll dist[maxn]; int c[maxn]; struct Edge { int v; ll w; Edge *next; };Edge e[maxn*10]; bool relax(int u,int v,ll w) { if(dist[u]+w<dist[v]){ dist[v]=dist[u]+w; return true; } return false; } void add_edge(int u,int v,ll w) ///插入邻接表的首部而非尾部,避免遍历 { Edge *pre=&e[u]; Edge *p=(Edge*)malloc(sizeof(Edge)); p->v=v;p->w=w; p->next=pre->next; pre->next=p; } bool spfa() { for(int i=1;i<=N;i++) dist[i]=(i==S)?0:INF; memset(vis,0,sizeof(vis)); memset(c,0,sizeof(c)); queue<int> q; q.push(S); vis[S]=1;c[S]++; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(Edge *p=e[u].next;p!=NULL;p=p->next){ ///遍历队首结点的每条出边 int v=p->v; ll w=p->w; if(relax(u,v,w)){ if(!vis[v]){ q.push(v); vis[v]=1; c[v]++; if(c[v]>N) return false; } } } } return true; }
没有AC不了的题,只有不努力的ACMER!