@zhangche0526
2017-02-25T06:37:13.000000Z
字数 3179
阅读 1073
以下部分内容转载自http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
时间复杂度:
这复杂度……也只有走投无路之时会用到了
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>using namespace std;const int MAXN=100;int head[MAXN+1],ecnt;struct node{int to,next,dis;} edge[MAXN+1];int dis[MAXN+1][MAXN+1];void add(int x,int y,int qz){ecnt++;edge[ecnt].to=y;edge[ecnt].next=head[x];head[x]=ecnt;dis[x][y]=qz;}bool lt(int x,int y){for(node redge=edge[head[x]];;redge=edge[redge.next]){if(redge.to==y) return true;if(!redge.next) break;}return false;}int m,n;void floyed(){memset(dis,0x7fffffff,sizeof(dis));for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(dis[i][j]>dis[i][k]+dis[k][j])dis[i][j]=dis[i][k]+dis[k][j];}
时间复杂度
复杂度低且稳定,但不能处理负边权图,最重要的是手写堆优化的Dijkstra洋洋洒洒上百行,易写错
其实Dijkstra与SPFA十分相似,只是Dijkstra通过贪心法减少了不必要的松弛操作
思路:
示例:


代码:
#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int MAXINT = 2147483647;const int MAXN = 1e4,MAXM=5e5;int dis[MAXN];int N,M,s;bool S[MAXN];int head[MAXN+1],ecnt;struct node{int next,to,value;} e[MAXM+1];void add(int x,int y,int z){ecnt++,e[ecnt].to=y,e[ecnt].next=head[x],head[x]=ecnt,e[ecnt].value=z;}struct dat{int v,id;} heap[2*MAXN+1];int heapSize;void put(dat x){int now,next;heap[++heapSize] = x;now = heapSize;while(now > 1){next=now >> 1;if(heap[now].v >= heap[next].v)break;swap(heap[now],heap[next]);now = next;}}dat get(){int now,next;dat res;res = heap[1];heap[1]=heap[heapSize--];now = 1;while(now * 2 <= heapSize){next = now * 2;if(next < heapSize && heap[next+1].v < heap[next].v)next++;if(heap[now].v <= heap[next].v) break;swap(heap[now],heap[next]);now = next;}return res;}void Dijkstra(int v0){int i;for(i=1;i<=N;i++) dis[i]=MAXINT;memset(S,false,sizeof(S));for(int tmp=head[v0];tmp;tmp=e[tmp].next){dis[e[tmp].to]=e[tmp].value;dat x;x.id=e[tmp].to,x.v=dis[e[tmp].to];put(x);}dis[v0] = 0;S[v0] = true;for(i=2; i<=N; i++){int u;do u=get().id;while(S[u]);S[u] = true;for(int tmp=head[u];tmp;tmp=e[tmp].next)if(!S[e[tmp].to])if(dis[u]+e[tmp].value<dis[e[tmp].to]){dis[e[tmp].to]=dis[u]+e[tmp].value;dat x;x.v=dis[e[tmp].to],x.id=e[tmp].to;put(x);}}}
时间复杂度:
不太稳定,但能处理负边权图
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAXINT=2147483647;const int MAXN=10000,MAXM=500000;int n,m,s;int head[MAXN+1],ecnt;struct node{int to,next,value;} edge[MAXM+1];void add(int x,int y,int z)ecnt++,edge[ecnt].to=y,edge[ecnt].next=head[x],head[x]=ecnt,edge[ecnt].value=z;}bool vis[MAXN+1];int dis[MAXN+1],queue[2*MAXN+5];int SPFA(int v0){memset(vis,false,sizeof(vis));for(int i=1;i<=n;i++) dis[i]=MAXINT;dis[v0]=0;vis[v0]=true;int h=0,t=1;queue[t]=v0;while(h<t){h=(h+1)%(2*n+5);//循环队列出队int u=queue[h];vis[u]=false;for(int tmp=head[u];tmp;tmp=edge[tmp].next)if(dis[edge[tmp].to]>dis[u]+edge[tmp].value){dis[edge[tmp].to]=dis[u]+edge[tmp].value;if(!vis[edge[tmp].to]){vis[edge[tmp].to]=true;t=(t+1)%(2*n+5);//循环队列入队queue[t]=edge[tmp].to;}}}}int main(){freopen("spfa.in","r",stdin);cin>>n>>m>>s;int u,v,w;for(int i=1;i<=m;i++){cin>>u>>v>>w;add(u,v,w);add(v,u,w);}//读入SPFA(s);for(int i=1;i<n;i++) cout<<dis[i]<<" ";//输出cout<<dis[n]<<endl;return 0;}