HDU 2544 关于最短路的三种解法

来源:互联网 发布:移动数据关闭还走流量 编辑:程序博客网 时间:2024/06/04 05:08

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

关于最短路的求法,当点的个数約小n<300的是候果断用floyd(n3方)跑,当点很多的时候则跑fifo优化的bellman-ford(n*m)或者dij(n*m,优先队列可以优化到m*lgn

1.数组dij:

#include<algorithm>#include<iostream> #include<cmath>#include<map>#include<string>#include<cstring>#include<vector> using namespace std;#define ll long long int#define maxn 200const int inf=0x7fffff;int n,t;int d[maxn],mp[maxn][maxn],vis[maxn];void dij(){    d[1]=0;    for(int i=0;i<=n;i++)    {        int mx,minf=inf;        for(int j=1;j<=n;j++)        {            if(minf>d[j]&&!vis[j])             {                minf=d[j];                mx=j;            }        }        vis[mx]=1;        for(int j=1;j<=n;j++)        {            if(d[j]>d[mx]+mp[mx][j]&&!vis[j])            {                d[j]=d[mx]+mp[mx][j];            }        }    }    if(d[n]!=inf) printf("%d\n",d[n]);    else printf("-1\n");    return ;     } int main(){       //freopen("in.txt","r",stdin);   int st,ed,v,m;    while(scanf("%d%d",&n,&m)!=EOF)    {             if(n==0) break;         for(int i=0;i<200;i++)         {             vis[i]=0;             d[i]=inf;             for(int j=0;j<200;j++)             {                 mp[i][j]=inf;             }         }            for(int i=0;i<m;i++)            {                             scanf("%d%d%d",&st,&ed,&v);            if(mp[st][ed]>=v)            {                            mp[st][ed]=v;                mp[ed][st]=v;                //cout<<mp[st][ed]<<endl;            }                  }dij();   }     }

2.优先队列优化的dij

#include<algorithm>#include<iostream> #include<cmath>#include<map>#include<string>#include<cstring>#include<vector> #include<queue>using namespace std;#define ll long long int#define maxn 10008typedef pair<int,int>pii;const int inf=0x7fffff;struct Edge{    int from,to,dist;    Edge(int u,int v,int d):from(u),to(v),dist(d){}};int n;vector<Edge>edges;vector<int>G[maxn];bool vis[maxn];int d[maxn];int p[maxn];void init(){    for(int i=0;i<n;i++) G[i].clear();    edges.clear();}void addedge(int from,int to,int dist){    edges.push_back(Edge(from,to,dist));          int m=edges.size();    G[from].push_back(m-1);}int dijstra(int s,int ed){    priority_queue<pii,vector<pii>,greater<pii> >Q;    for(int i=0;i<=n;i++) d[i]=inf;    d[s]=0;    memset(vis,0,sizeof(vis));    Q.push(make_pair(d[s],s));    while(!Q.empty())    {        pii x = Q.top();Q.pop();        int u=x.second;        if(vis[u]) continue;        vis[u]=1;        for(int i=0;i<G[u].size();i++)        {                 Edge& e=edges[G[u][i]];                 if(d[e.to]>d[u]+e.dist)                        {                d[e.to]=d[u]+e.dist;                p[e.to]=G[u][i];                Q.push(make_pair(d[e.to],e.to));            }                }    }    printf("%d\n",d[ed]);}int main(){    int m;   //freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m)!=EOF)    {             if(n==0) break;         int u,v,c;         init();                   for(int i=0;i<m;i++)          {              scanf("%d%d%d",&u,&v,&c);              //cout<<u<<v<<c<<endl;              addedge(u,v,c);              addedge(v,u,c);                        }          dijstra(1,n);     }       }

3.bellman-ford

include<algorithm>#include<iostream> #include<cmath>#include<map>#include<string>#include<cstring>#include<vector> #include<queue>using namespace std;#define ll long long int#define maxn 10008typedef pair<int,int>pii;const int inf=0x7fffff;struct Edge{    int to,dist;    Edge(int v,int d):to(v),dist(d){}};int n;vector<Edge>edge[maxn];bool vis[maxn];int d[maxn];int cnt[maxn];void init(){    for(int i=0;i<n;i++) edge[i].clear();}void addedge(int from,int to,int dist){    edge[from].push_back(Edge(to,dist));      }void bell_man(int st,int ed){    queue<int>q;    memset(vis,0,sizeof(vis));    memset(cnt,0,sizeof(cnt));    for(int i=0;i<=n;i++) d[i]=inf;    d[st]=0;    vis[st]=1;    q.push(st);    while(!q.empty())    {        int u=q.front();q.pop();        vis[u]=0;        for(int i=0;i<edge[u].size();i++)        {            Edge e=edge[u][i];             if(d[u]<inf&&d[e.to]>d[u]+e.dist)             {                 d[e.to]=d[u]+e.dist;                 if(!vis[e.to])                 {                     q.push(e.to);                     vis[e.to]=1;                     if(++cnt[e.to]>n) return ;                 }             }        }     }      printf("%d\n",d[ed]);    }int main(){    int m;   //freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m)!=EOF)    {             if(n==0) break;         int u,v,c;         init();                   for(int i=0;i<m;i++)          {              scanf("%d%d%d",&u,&v,&c);              //cout<<u<<v<<c<<endl;              addedge(u,v,c);             addedge(v,u,c);                        }         bell_man(1,n);     }       }
4、floyd

#include<algorithm>#include<iostream> #include<cmath>#include<map>#include<string>#include<cstring>#include<vector> using namespace std;#define ll long long int#define maxn 200const int inf=0x7fffff;int n;int d[maxn][maxn],mp[maxn][maxn]; void floyd() {     for(int k=1;k<=n;k++)     {         for(int i=1;i<=n;i++)         {             for(int j=1;j<=n;j++)             {                 d[i][j]=min(d[i][j],d[i][k]+d[k][j]);             }         }     } }int main(){       //freopen("in.txt","r",stdin);   int st,ed,v,m;    while(scanf("%d%d",&n,&m)!=EOF)    {             if(n==0) break;         for(int i=0;i<200;i++)         {                               for(int j=0;j<200;j++)             {                 if(i==j) d[i][j]=0;                 else d[i][j]=inf;             }         }            for(int i=0;i<m;i++)            {                             scanf("%d%d%d",&st,&ed,&v);            if(d[st][ed]>=v)            {                            d[st][ed]=v;                d[ed][st]=v;                //cout<<mp[st][ed]<<endl;            }                  }        floyd();        printf("%d\n",d[1][n]);   }     }

0 0