您的位置:首页 > 其它

HDU 2066 一个人的旅行

2016-05-22 21:20 302 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2066

题意:应该看懂了。。。

思路:就是简单的最短路径的模板,下面我用三种方法来做这道题。

(1)Floyd:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<climits>
#include<queue>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int Max=1001;
int map[Max][Max],endd[Max];
void floyd(int n)
{
int i,j,k;
for(i=0; i<=n; i++)
{
for(j=0; j<=n; j++)
{
if(map[j][i]!=INF)
{
for(k=0; k<=n; k++)
{
if(map[j][i]+map[i][k]<map[j][k])
{
map[j][k]=map[j][i]+map[i][k];
}
}
}

}
}
}
int main()
{
int T,S,D,temp=0,i,j;
while(cin>>T>>S>>D)
{
memset(endd,0,sizeof(endd));
memset(map,INF,sizeof(map));
for(i=0; i<Max; i++)
{
map[i][i]=0;
}
int a,b,time,lj,xq;//lj表示临近城市,xq表示想去的城市。
for(i=1; i<=T; i++)
{
cin>>a>>b>>time;
if(temp<=max(a,b))
{
temp=max(a,b);//确定临界矩阵,防止超时。
}
if(time<map[a][b])
{
map[a][b]=map[b][a]=time;
}
}
for(i=1; i<=S; i++)
{
cin>>lj;
map[0][lj]=map[lj][0]=0;
}
for(i=1; i<=D; i++)
{
cin>>xq;
endd[i]=xq;//想去的城市即终止点。
}
floyd(temp);
int result=INF;
for(i=1; i<=D; i++)
{

if(map[0][endd[i]]<result)
{
result=map[0][endd[i]];//从出发点到想去的城市的最短路就是所求的最短距离。
}
}
printf("%d\n",result);
}

return 0;
}


(2)Dijkstar:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<climits>
#include<queue>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int Max=1001;
int map[Max][Max],vis[Max],dis[Max],endd[Max];
void Dijkstar(int n)
{
int i,j,min;
memset(vis,0,sizeof(vis));
int pos=0;
vis[pos]=1;
dis[pos]=0;
for(i=1; i<=n; i++)
{
dis[i]=map[pos][i];//对dis进行赋值。
}
for(i=0; i<n-1; i++)
{
min=INF;
for(j=1; j<=n; j++)

{
if(vis[j]==0&&min>dis[j])
{
min=dis[j];
pos=j;
}
}//找出此城市的最短路。
if(min<INF)
vis[pos]=1;
else
{
break;
}
for(j=1; j<=n; j++)
{
if(vis[j]==0&&dis[j]>dis[pos]+map[pos][j])
{
dis[j]=dis[pos]+map[pos][j];//对dis进行更新,此时的dis和prim中的low不一样,prim中low表示的是从此城市到另外一个城市的最短路径,而这里的dis是指从出发点到此城市的最短路径。
}
}
}
}
int main()//主函数和Dijkstar中的一样,只是求最短路的方法不一样了。
{
int t,i,j,T,S,D;

while(cin>>T>>S>>D)
{
int temp=0;
memset(endd,0,sizeof(endd));
for(i=0; i<Max; i++)
{
for(j=0; j<Max; j++)
{
if(i==j)
map[i][j]=0;
else
{
map[i][j]=INF;
}
}
}
int a,b,time,lj,xq;
for(i=0; i<T; i++)
{
cin>>a>>b>>time;
if(temp<max(a,b))
{
temp=max(a,b);
}
if(time<map[a][b])
{
map[a][b]=map[b][a]=time;
}
}
for(i=0; i<S; i++)
{
cin>>lj;
map[0][lj]=map[lj][0]=0;
}
for(i=0; i<D; i++)
{
cin>>xq;
endd[i]=xq;
}
Dijkstar( temp);
int result=INF;
for(i=0; i<D; i++)
{
if(dis[endd[i]]<result)
{
result=dis[endd[i]];
}
}
printf("%d\n",result);
}
return 0;
}


(3)spfa

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<climits>
#include<queue>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int Max=1001;
int map[Max][Max],vis[Max],dis[Max],endd[Max],start[Max];
int S;
int temp;
void spfa()
{
int i,j;
queue<int>q;//定义一个对列q
memset(vis,0,sizeof(vis));
for(i=1;i<=temp;i++)
{
dis[i]=INF;//对dis赋值。
}
for(i=0;i<S;i++)
{
dis[start[i]]=0;
q.push(start[i]);
vis[start[i]]=1;
}//将第一个城市入队
while(!q.empty())//将剩余的城市依次入队
{
int ans=q.front();
q.pop();
vis[ans]=0;
for(i=1;i<=temp;i++)
{
if(dis[i]>dis[ans]+map[ans][i])
{
dis[i]=dis[ans]+map[ans][i];
if(vis[i]==0)
{
q.push(i);
vis[i]=1;
}
}

}

}
}
int main()//与前面的方法雷同
{
int t,i,j,T,D;
while(cin>>T>>S>>D)
{
temp=0;
memset(endd,0,sizeof(endd));
for(i=0; i<Max; i++)
{
for(j=0; j<Max; j++)
{
if(i==j)
map[i][j]=0;
else
{
map[i][j]=INF;
}
}
}
int a,b,time,lj,xq;
for(i=0; i<T; i++)
{
cin>>a>>b>>time;
if(temp<max(a,b))
{
temp=max(a,b);
}
if(time<map[a][b])
{
map[a][b]=map[b][a]=time;
}
}
for(i=0; i<S; i++)
{
cin>>lj;
start[i]=lj;
}
for(i=0; i<D; i++)
{
cin>>xq;
endd[i]=xq;
}
spfa();
int result=INF;
for(i=0; i<D; i++)
{
if(dis[endd[i]]<result)
{
result=dis[endd[i]];
}
}
printf("%d\n",result);
}
return 0;
}


基本上这三个方法就是最短路径的模板。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: