【最短路模板】HDU 2544

来源:互联网 发布:淘宝ka商家是什么意思 编辑:程序博客网 时间:2024/06/09 20:01

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544



Bellman-Ford

#include<stdio.h>#include<limits.h>#define N 10005#define INF INT_MAX >> 1struct Edge{        int u,v;        //起点 终点int w;          //权};int v,e;//点、边数int dis[N];        Edge edge[N*2];int Bellman_Ford(int src,int des){int i,j;dis[src]=0;for(i=1;i<=v;++i){for(j=1;j<=e*2;++j){if(dis[edge[j].v]>dis[edge[j].u]+edge[j].w){dis[edge[j].v]=dis[edge[j].u]+edge[j].w;}}}for(i=1;i<=e*2;++i)if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)return -1;return dis[des];}void Init(){int i;for(i=1;i<=v;++i){dis[i]=INF;}}void Add(){int i;for(i=1;i<=e;++i){scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);edge[i+e].v=edge[i].u;edge[i+e].u=edge[i].v;edge[i+e].w=edge[i].w;}}void Solve(){if(Bellman_Ford(1,v)!=-1)printf("%d\n",dis[v]);}int main(){int i,j;while(~scanf("%d%d",&v,&e)&&(v+e)){Init();Add();Solve();}return 0;}


Dijkstar


#include<cstdio>#include<iostream>#include<cstring>#include<climits>using namespace std;#define N 110#define INF INT_MAX >> 1 int v,e;int map[N][N];int vis[N];int dis[N];void Init(){int i,j;for(i=1;i<=v;++i){dis[i]=INF;for(j=1;j<=v;++j)map[i][j]=INF;}memset(vis,0,sizeof(vis));}void Add(){int i,j;int a,b,c;for(i=1;i<=e;++i){scanf("%d%d%d",&a,&b,&c);if(map[a][b]>c){map[a][b]=map[b][a]=c;}}}int Dijkstar(int src,int des){int i,j;int mmin,k;for(i=1;i<=v;++i)dis[i]=map[src][i];dis[src]=0;vis[src]=1;for(i=1;i<=v;++i){mmin=INF;for(j=1;j<=v;++j)if(!vis[j]&&dis[j]<mmin)mmin=dis[k=j];if(mmin==INF)break;vis[k]=1;for(j=1;j<=v;++j)if(!vis[j]&&dis[j]>dis[k]+map[k][j])dis[j]=dis[k]+map[k][j];}return dis[des];}void Solve(){printf("%d\n",Dijkstar(1,v));}int main(){while(~scanf("%d%d",&v,&e)&&(v+e)){Init();Add();Solve();}return 0;}


SPFA(邻接矩阵)


#include<iostream>#include<cstdio>#include<climits>#include<queue>#include<algorithm>using namespace std;#define N 110#define INF INT_MAX>>1int v,e;//点,边int map[N][N],dis[N];int times[N];int vis[N];queue<int> q;void Init(){int i,j;for(i=1;i<=v;++i){dis[i]=INF;for(j=1;j<=v;++j)map[i][j]=INF;}memset(vis,0,sizeof(vis));memset(times,0,sizeof(times));}int SPFA(int src,int des){int i,j;while(!q.empty()) q.pop();dis[src]=0;vis[src]=1;q.push(src);while(!q.empty()){int cur=q.front();q.pop();vis[cur]=0;//出队标记为0for(i=1;i<=v;++i){if(dis[i]>dis[cur]+map[cur][i]){dis[i]=dis[cur]+map[cur][i];//能松弛就松弛if(!vis[i])//不在队列中则加入,然后更新所有以前经过此点的最短路径{q.push(i);vis[i]=1;times[i]++;if(times[i]>v)//某点入队次数超过顶点数量return -1;//有负环}}}}return dis[des];}void Add(){int a,b,c;int i;for(i=0;i<e;++i){scanf("%d%d%d",&a,&b,&c);if(c<map[a][b])map[a][b]=map[b][a]=c;}}void Solve(){printf("%d\n",SPFA(1,v));}int main(){while(~scanf("%d%d",&v,&e)&&(v+e)){Init();Add();Solve();}return 0;}


SPFA(邻接表STL实现)



#include<iostream>#include<cstdio>#include<climits>#include<queue>#include<vector>#include<algorithm>using namespace std;#define N 110#define INF INT_MAX>>1struct node{int v,w;//终点,长度node(){}node(int v,int w){this->v=v;this->w=w;}};int v,e;//点,边int dis[N];int vis[N];int times[N];queue<int> q;vector<node> edge[N];//邻接表void Init(){int i,j;for(i=1;i<=v;++i){dis[i]=INF;edge[i].clear();}memset(vis,0,sizeof(vis));memset(times,0,sizeof(times)); }int SPFA(int src,int des){int i,j;while(!q.empty()) q.pop();dis[src]=0;vis[src]=1;q.push(src);while(!q.empty()){int cur=q.front();q.pop();vis[cur]=0;//出队标记为0for(i=0;i<edge[cur].size();++i){if(dis[edge[cur][i].v]>dis[cur]+edge[cur][i].w){dis[edge[cur][i].v]=dis[cur]+edge[cur][i].w;//能松弛就松弛  if(!vis[edge[cur][i].v])//不在队列中则加入,然后更新所有以前经过此点的最短路径  {q.push(edge[cur][i].v);vis[edge[cur][i].v]=1;times[edge[cur][i].v]++;  if(times[edge[cur][i].v]>v)//某点入队次数超过顶点数量  return -1;//有负环  }}}}return dis[des];}void Add(){int a,b,c;int i;for(i=0;i<e;++i){scanf("%d%d%d",&a,&b,&c);node pash1(b,c),pash2(a,c);edge[a].push_back(pash1);edge[b].push_back(pash2);}}void Solve(){printf("%d\n",SPFA(1,v));}int main(){while(~scanf("%d%d",&v,&e)&&(v+e)){Init();Add();Solve();}return 0;}


SPFA(邻接表非STL实现)


#include<iostream>#include<cstdio>#include<climits>#include<queue>#include<vector>#include<algorithm>using namespace std;#define N 110#define INF INT_MAX>>1struct node{int v,w,next;//终点,长度}edge[N*N];int v,e;//点,边int dis[N];int vis[N];int times[N];queue<int> q;int k;int headlist[N];void Init(){int i;k=1;for(i=1;i<=v;++i){dis[i]=INF;}memset(vis,0,sizeof(vis));memset(times,0,sizeof(times)); memset(headlist,0,sizeof(headlist));}void AddEdge(int u,int v,int w){edge[k].v=v;    edge[k].w=w;    edge[k].next=headlist[u];    headlist[u]=k++;}int SPFA(int src,int des){int i,j;while(!q.empty()) q.pop();dis[src]=0;vis[src]=1;q.push(src);while(!q.empty()){int cur=q.front();q.pop();vis[cur]=0;//出队标记为0for(i=headlist[cur];i;i=edge[i].next)        {            if(dis[edge[i].v]>dis[cur]+edge[i].w)            {                dis[edge[i].v]=dis[cur]+edge[i].w;//能松弛就松弛                  if(!vis[edge[i].v])//不在队列中则加入,然后更新所有以前经过此点的最短路径                  {                    q.push(edge[i].v);                    vis[edge[i].v]=1; times[edge[i].v]++;  if(times[edge[i].v]>v)//某点入队次数超过顶点数量  return -1;//有负环  }}}}return dis[des];}void Add(){int a,b,c;int i;for(i=0;i<e;++i){scanf("%d%d%d",&a,&b,&c);AddEdge(a,b,c);AddEdge(b,a,c);}}void Solve(){printf("%d\n",SPFA(1,v));}int main(){while(~scanf("%d%d",&v,&e)&&(v+e)){Init();Add();Solve();}return 0;}


0 0