您的位置:首页 > 其它

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

2015-11-01 18:42 330 查看
链接: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]);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: