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

链接: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 200
const 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 10008
typedef 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 10008
typedef 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 200
const 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]); } }

你可能感兴趣的:(HDU 2544 关于最短路的三种解法)