最短路简化版(邻接矩阵和邻接表)

经历一周忙碌的工作后,蒜头君想趁着周末好好游玩一番。蒜头君想去好多好多地方,他想去南锣鼓巷吃各种好吃的,想去颐和园滑冰,还想去怀柔滑雪场滑雪……可是时间有限,蒜头君并不能玩遍所有的地方,最后他决定去几个离他较近的。

我们知道蒜头君一共想去 NN 个地方玩耍,编号从 11 到 NN,并且知道了蒜头君所在地方的编号 CC,以及 MM 条路径。现在蒜头君想让你帮他算一算,他到每个地方分别需要经过多少个地方?

输入格式

第一行输入三个正整数 N, M, CN,M,C。代表蒜头君想去 NN 个地方,有 MM 条路径,蒜头君在编号为 CC 的地方。1 \leq N, C \leq 10001N,C10001 \leq C \leq N1CN1 \leq M \leq 100001M10000

保证没有重复边,且图中所有点互相连通。

输出格式

输出 NN 行,按编号从小到大,输出结果。第 ii行表示蒜头君到编号为 ii 的地方,需要经过多少个地方。

样例输入
5 5 2
1 2
2 3
2 4
3 4
3 5
样例输出
1
0
1
1

2

开始邻接矩阵做,超时一组,看着觉得只超了一点,实际上只是超时了程序就停止了。然后改用邻接表,其实在这题上邻接表优势特别明显。题目思路很简单,直接bfs加一个计数数组。

邻接矩阵(有一组未过)

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int G[1005][1005],ans[1005];
int n,m,c;
void fun()
{
    int flag[1005]={0};
    int last=c;
    int cnt=0;
    int foll;
    queue<int>q;
    flag[c]=1;
    q.push(c);
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
 //       if(temp==x)
 //           break;
        ans[temp]=cnt;
        for(int i=1;i<=1000;i++)
        {
            if(G[temp][i]==1&&!flag[i])
            {
                flag[i]=1;
                q.push(i);
                foll=i;
            }
        }
        if(temp==last)
        {
            cnt++;
            last=foll;
        }
    }
 //   return cnt;
}
int main()
{
    cin>>n>>m>>c;
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        G[a][b]=1;
        G[b][a]=1;
    }
    for(int i=1;i<=n;i++)
    {
//        int ans=fun(i);
        fun();
        cout<<ans[i]<<endl;
    }
    return 0;
}
邻接表(AC)

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
int G[1005][1005],ans[1005];
vector<vector<int> >arr(1005);
int n,m,c;
void fun()
{
    int flag[1005]={0};
    int last=c;
    int cnt=0;
    int foll;
    queue<int>q;
    flag[c]=1;
    q.push(c);
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
 //       if(temp==x)
 //           break;
        ans[temp]=cnt;
        for(int i=0;i<arr[temp].size();i++)
        {
            if(!flag[arr[temp][i]])
            {
                flag[arr[temp][i]]=1;
                q.push(arr[temp][i]);
                foll=arr[temp][i];
            }
        }
        if(temp==last)
        {
            cnt++;
            last=foll;
        }
    }
 //   return cnt;
}
int main()
{
    cin>>n>>m>>c;
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        arr[a].push_back(b);
        arr[b].push_back(a);
    }
    for(int i=1;i<=n;i++)
    {
//        int ans=fun(i);
        fun();
        cout<<ans[i]<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没想好叫什么名字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值