关于这道题有一点多元所以我们很多人都理解不了,这道题的关键就是这个Floyd 算法这个算法我们,这个算法其实很简单滴,就是有三层循环,第一次循环作为中心结点,后两次循环就是遍历结点了。
具体就看每一点都可以通过其他点为媒介到达,所以我们这个算法就是将每一个点到其他的点的最短距离保存下来,以动态规划为基础的一个算法。就比如我从山西去青岛,通过石家庄这个点和北京这个点,其中通过石家庄这个点的距离是1000公里,而通过北京这个点是1500公里,这样我就把我到青岛的距离缩到最小1000公里。其中北京和石家庄相当于中间点。了解了这个算法之后呢,我们接下来就得用一个特别的输入方式,具体代码讲解如下。
int a,b,c;cin>>a>>b>>c;这个是我们的三个初值,结点数,道路数,和对应的付费
vector<vector<int> >maps(a+10,vector<int>(a+10,0));这个矩阵是保存临接矩阵
vector<int>vis(a+1,0);判断对应点是不是起始点和结束点
for(int i=1;i<=a;i++)
{
for(int i1=1;i1<=a;i1++)
{
maps[i][i1]=(i==i1)?0:1e9;
}
}
for(int i=0;i<b;i++)
{
int x,y,z;cin>>x;这个x是起始点
vis[x]=1;端点处的终点站的值设为1
while(1)
{
cin>>y>>z;
maps[x][z]=maps[z][x]=min(maps[x][z],y);
x=z;
char ch=getchar();
if(ch=='\n')break;当输入回车的时候结束一行的输入
}
vis[x]=1;终点站的值也设为1
}
for(int i=1;i<=a;i++) Flody算法
{
for(int i1=1;i1<=a;i1++)
{
for(int i2=1;i2<=a;i2++)
{
maps[i1][i2]=min(maps[i1][i2],maps[i1][i]+maps[i][i2]);
}
}
}
之后我们将每一个价钱的最远距离保存下来,并将这个对应到达的地点,就和第一道题那样,将该地点保存在对应空间内,就跟临接表一样。具体代码详解如下
map<int,int>hi;这个是方便保存用的就是hi[int(对应钱数)]=最远的距离
vector<int>go[210];这个是临接表的储存法
for(int i=1;i<=a;i++)
{
hi.clear();每一次使用要清以下,以防重复使用
for(int i1=1;i1<=a;i1++)
{
if(i==i1||maps[i][i1]==1e9)continue;边界条件直接跳过
hi[maps[i][i1]/c+2]=max(maps[i][i1],hi[maps[i][i1]/c+2]);保存该价钱的最远距离
}
for(int i1=1;i1<=a;i1++)
{
if(maps[i][i1]==1e9)continue;边界条件直接跳过
if(maps[i][i1]==hi[maps[i][i1]/c+2]||i==i1||vis[i1]==1)go[i].push_back(i1);
这个是临界表形式的储存方式,
如果这个价钱的最远距离找到了,可以出站,还有就是两端终点站可以出站,
还有就是出发站可以出战分别对应以上三个条件
}
}
之后就是用深度优先遍历的形式判断从对应点出发可以到达哪些点,具体操作如下跟第一题一样。
vector<int>go[210];
int bo[210];判断该结点是否遍历过
void dfs(int p)
{ bo[p]=1;
for(int i=0;i<go[p].size();i++)
{
if(bo[go[p][i]]==0)
dfs(go[p][i]);
}
}
int p;cin>>p;
while(p--)
{
memset(bo,0,sizeof(bo));每次都要重置
int sm;cin>>sm;
dfs(sm);开始从该结点处遍历。
vector<int>ji;
for(int i=1;i<=a;i++)把遍历过的点就是能到达的点都按顺序存起来
{
if(bo[i]!=0)ji.push_back(i);
}
for(int i=0;i<ji.size();i++)最后输出
{
if(i==0)cout<<ji[i];
else cout<<" "<<ji[i];
}
cout<<endl;
}
以上就是我们的具体步骤
接下来就是我们的最终代码
#include<bits/stdc++.h>
using namespace std;
vector<int>go[210];
int bo[210];
void dfs(int p)
{ bo[p]=1;
for(int i=0;i<go[p].size();i++)
{
if(bo[go[p][i]]==0)
dfs(go[p][i]);
}
}
int main()
{
int a,b,c;cin>>a>>b>>c;
vector<vector<int> >maps(a+10,vector<int>(a+10,0));
vector<int>vis(a+1,0);
for(int i=1;i<=a;i++)
{
for(int i1=1;i1<=a;i1++)
{
maps[i][i1]=(i==i1)?0:1e9;
}
}
for(int i=0;i<b;i++)
{
int x,y,z;cin>>x;
vis[x]=1;
while(1)
{
cin>>y>>z;
maps[x][z]=maps[z][x]=min(maps[x][z],y);
x=z;
char ch=getchar();
if(ch=='\n')break;
}
vis[x]=1;
}
for(int i=1;i<=a;i++)
{
for(int i1=1;i1<=a;i1++)
{
for(int i2=1;i2<=a;i2++)
{
maps[i1][i2]=min(maps[i1][i2],maps[i1][i]+maps[i][i2]);
}
}
}
map<int,int>hi;
for(int i=1;i<=a;i++)
{
hi.clear();
for(int i1=1;i1<=a;i1++)
{
if(i==i1||maps[i][i1]==1e9)continue;
hi[maps[i][i1]/c+2]=max(maps[i][i1],hi[maps[i][i1]/c+2]);
}
for(int i1=1;i1<=a;i1++)
{
if(maps[i][i1]==1e9)continue;
if(maps[i][i1]==hi[maps[i][i1]/c+2]||i==i1||vis[i1]==1)go[i].push_back(i1);
}
}
int p;cin>>p;
while(p--)
{
memset(bo,0,sizeof(bo));
int sm;cin>>sm;
dfs(sm);
vector<int>ji;
for(int i=1;i<=a;i++)
{
if(bo[i]!=0)ji.push_back(i);
}
for(int i=0;i<ji.size();i++)
{
if(i==0)cout<<ji[i];
else cout<<" "<<ji[i];
}
cout<<endl;
}
}