您的位置:首页 > 其它

HDOJ 2544 最短路(四种做法)

2016-06-20 21:49 423 查看
DFS(因为是求总时间,只需将简单的深搜求最短路的方法,二维数组清零即可):

原始的DFS:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int INF=99999999;//正无穷
int minn;
int n,e[105][105],book[105];

void dfs(int cur,int dis)
{
int j;
//已经超过前面查找的最短路径,就不需要在查找了
if(dis>minn)
return;
if(cur==n)//到达了
{
minn=min(dis,minn);
return;
}

for(j=1;j<=n;j++)//从1号城市到n号城市依次尝试
{//判断当前城市cur到城市j是否有路,并判断城市j是否已经走过
if(e[cur][j]!=INF&&book[j]==0)
{
book[j]=1;//标记已经走过
dfs(j,dis+e[cur][j]);//从城市j再出发,继续寻找
book[j]=0;
}
}
return;
}
int main()
{
int i,j,m,a,b,c;
while(~scanf("%d%d",&n,&m)&&(n||m))
{
//初始化二维矩阵
memset(book,0,sizeof(book));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i==j)    e[i][j]=0;//自己
else    e[i][j]=INF;

//读入城市之间的距离
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[a][b]=c;
e[b][a]=c;
}
minn=INF;
//从1号城市出发
book[1]=1;
dfs(1,0);
printf("%d\n",minn);
}
return 0;
}
/*
5  8//五个城市,10条路径
1 2 2
1 5 10
2 3 3
2 5 7
3 1 4
3 4 4
4 5 5
5 3 3
*/


修改后的DFS:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int INF = 999999;
int minn;
int n,m,e[105][105],book[105];

void dfs(int cur,int dis)
{
int j;
if(dis>minn)
return;
if(cur==n)//到达了终点
{
minn=dis;
return;
}
for(int i=2;i<=n;i++)
{
if(e[cur][i]&&!book[i])
{
book[i]=1;
dfs(i,dis+e[cur][i]);
book[i]=0;//回溯
}
}
return;
}
int main()
{

while(~scanf("%d%d",&n,&m)&&(n||m))
{
memset(e,0,sizeof(e));
memset(book,0,sizeof(book));

int a,b,c;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[a][b]=c;
e[b][a]=c;
}
//book[1]=1;
minn=INF;
dfs(1,0);
printf("%d\n",minn);
}
return 0;
}


Dijkstra:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int INF = 99999999;
int main()
{
int e[105][105],dis[105],book[105];
int n,m;
while(~scanf("%d%d",&n,&m)&&(n||m))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j)    e[i][j]=0;
else    e[i][j]=INF;
int t1,t2,t3;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&t1,&t2,&t3);
e[t1][t2]=t3;//双向边
e[t2][t1]=t3;
}

//初始化dis数组,哲理是1号顶点到其余各顶点的初始路程
for(int i=1;i<=n;i++)
dis[i]=e[1][i];

memset(book,0,sizeof(book));//初始化
book[1]=0;//因为1点是源点

int minn,u,v;
//Dijkstra算法核心语句
for(int i=1;i<=n-1;i++)//n-1
{
//找到离1号顶点最近的顶点
//是每次都要找
minn=INF;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]<minn)
{
minn=dis[j];
u=j;
}
}
book[u]=1;//一个新的起点
for(v=1;v<=n;v++)
{
if(e[u][v]<INF)
{
if(dis[v]>dis[u]+e[u][v])
dis[v]=dis[u]+e[u][v];
}
}
}

//输出
printf("%d\n",dis
);
}
return 0;
}
/*
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
*/


Floyd:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int INF = 99999999;
int main()
{
int e[105][105],dis[105],book[105];
int n,m;
while(~scanf("%d%d",&n,&m)&&(n||m))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j)    e[i][j]=0;
else    e[i][j]=INF;
int t1,t2,t3;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&t1,&t2,&t3);
e[t1][t2]=t3;//双向边
e[t2][t1]=t3;
}
memset(book,0,sizeof(book));//初始化
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(e[i][j]>e[i][k]+e[k][j]) e[i][j]=e[i][k]+e[k][j];
printf("%d\n",e[1]
);
}
return 0;
}
/*
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: