首页 > 试题广场 >

【模板】单源最短路1

[编程题]【模板】单源最短路1
  • 热度指数:11215 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给你一个无向图,图中包含 5000 个点 m 个边,任意两个点之间的距离是 1 ,无重边或自环。请求出1号点到n号点的最短距离。

注意:图中可能存在孤立点,即存在点与任意点都没有边相连

如果1号点不能到达n号点,输出-1.

输入描述:
第一行两个整数n和m,表示图的点和边数。
接下来m行,每行两个整数u,v,表示u到v有一条无向边。



输出描述:
输出一行,表示1到n的最短路,如不存在,输出-1.
示例1

输入

4 4
1 2
2 4
3 4
3 1

输出

2
示例2

输入

4 3
1 2
2 3
3 1

输出

-1

说明

1号点不能到4号点。 
这题是有问题吗???
发表于 2022-03-19 16:13:00 回复(5)
题目用例有坑,第一行输入得知点数是469个点,第二行输入是边,然而边的终点是499,已经超过点数了
发表于 2022-06-08 10:07:50 回复(3)

大佬们,跟gpt学的,提交后显示第13个测试用例结果错了。但是我没看出问题在哪,有没有人指点一下

from collections import deque, defaultdict
import sys
def shortest_path(n, edges):
    graph = defaultdict(list)
    for u,v in edges:
        graph[u].append(v)
        graph[v].append(u)
    queue = deque([1])
    distances = {1:0}
    while queue:
        cur = queue.popleft()
        for neighbor in graph[cur]:
            if neighbor not in distances:
                distances[neighbor] = distances[cur] + 1
                queue.append(neighbor)
            if neighbor == n:
                print(distances[neighbor])
                return
    print(-1)
edges = []
n,m = input().split()
for line in sys.stdin:
    u,v = line.split()
    edges.append( (int(u), int(v)) )
shortest_path(int(n), edges)
发表于 2024-08-21 20:03:24 回复(3)
#include <climits>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int main() {
    int n = 0, m = 0, u = 0, v = 0;
    cin >> n >> m;
    n--;
    vector<queue<int>> table(5000, queue<int>());
    vector<int> dist(5000, INT_MAX);
    vector<int> flag(5000, 0);
    for (int i = 0; i < m; i++) {
        cin >> u >> v;
        u--;
        v--;
        table[u].push(v);
        table[v].push(u);
        if (!u) {
            dist[v] = 1;
            flag[v] = 1;
        }
        if (!v) {
            dist[u] = 1;
            flag[u] = 1;
        }
    }
    dist[0] = 0;
    flag[0] = 1;
    int k = 5000;
    if (k > m) k = m;
    while (k--&&!flag[n]) {
        for (int i = 1; i < 5000; i++) {
            if (flag[i]) {
                while (!table[i].empty()) {
                    if (dist[i] + 1 < dist[table[i].front()]) dist[table[i].front()] = dist[i] + 1;
                    table[i].pop();
                }
            }
        }
        for (int i = 0; i < 5000; i++) {
            if (dist[i] < INT_MAX) flag[i] = 1;
        }
    }
    if (flag[n]) cout << dist[n] << endl;
    else cout << -1 << endl;
    return 0;
}

发表于 2023-04-10 17:19:08 回复(0)
import collections 

def bfs_sin(start,target,graph):
    dp = collections.deque()
    v = set()
    dp.append(start)
    res = {start:0}
    while dp:
        u = dp.popleft()
        if u == target:
            return res[target]
        for i in graph[u]:
            if i not in v:
                v.add(i)
                res[i] = res[u] + 1
                dp.append(i)
    return '-1'
            
n,m = map(int,input().split())
graph = collections.defaultdict(list)
for i in range(m):
    u,v = map (int,input().split())
    graph[u].append(v)
    graph[v].append(u)
print(bfs_sin(1,n,graph))

发表于 2025-04-19 19:22:52 回复(0)
这一题比较坑,因为点的总数是5000个固定的。输入中的n不是点的数量,这一点要注意。

#include <functional>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;

int main() {
    int n, m, u, v;
    cin >> n >> m;
    vector<set<int>> nei(5001);
    while(m--) {
        cin >> u >> v;
        nei[u].insert(v);
        nei[v].insert(u);
    }
    vector<int> des(5001, -1);
    vector<bool> flag(5001, false);
    queue<int> pq;
    des[1] = 0;
    pq.push(1);
    while(!pq.empty()) {
        int u = pq.front();
        pq.pop();
        if(flag[u]) continue;
        flag[u] = true;
        int d = des[u] + 1;
        for(auto &v : nei[u]) {
            if(des[v] == -1) {
                if(v == n) {
                    cout << d;
                    return 0;
                }
                des[v] = d;
                pq.push(v);
            }
        }
    }
    cout << -1;
}
// 64 位输出请用 printf("%lld")

发表于 2025-03-25 13:20:32 回复(0)
import sys
from collections import deque, defaultdict


def bfs_shortest_path(n, m, edges, start, target):
    # 创建邻接表
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)
    
    # 初始化距离数组
    dist = [-1] * (n + 1)
    dist[start] = 0
    
    # BFS 队列
    queue = deque([start])
    
    while queue:
        node = queue.popleft()
        for neighbor in graph[node]:
            if dist[neighbor] == -1:  # 未访问
                dist[neighbor] = dist[node] + 1
                queue.append(neighbor)
                # 如果找到目标节点,直接返回距离
                if neighbor == target:
                    return dist[target]
    
    # 如果 BFS 结束还未找到目标节点,返回 -1 表示无法到达
    return -1

# 示例用法
f = 5000  # 节点数
n, m = map(int, input().split())

edges = []
# edges = [(1, 2), (2, 3), (1, 3), (3, 4), (4, 5)]  # 示例边
for i in range(m):
    u, v = map(int, input().split())
    edges.append((u,v))

start = 1  # 起点
target = n  # 目标点

print(bfs_shortest_path(f, m, edges, start, target))

GPT给的,挺标准
发表于 2024-12-05 00:28:36 回复(0)
#include <stdlib.h>
#include <string.h>
#define n 5009
typedef struct node{
    int dest;
    struct node* to;
}node;

node* adj[n];
int visit[n],dist[n],q[n];

int bfs(int a){
    int f=0,r=0;
    q[r++]=1;
    visit[1]=1,dist[1]=0;
    while (f<r) {
        int u=q[f++];
        node* p=(node*)malloc(sizeof(node));
        p=adj[u];
        while (p!=NULL) {
               int v=p->dest;
               if(!visit[v]){
                  visit[v]=1;
                  dist[v]=dist[u]+1;
                  q[r++]=v;
                  if (v==a) {
                      return dist[v];
                  }

               }
               p=p->to;
        }
    }
    return -1;
}

int main() {
    int a, b,s,e;
    scanf("%d %d", &a, &b);
    for(int i=0;i<n;i++){
        visit[i]=0;
        dist[i]=-1;
        adj[i]=NULL;
    }
    while (b--) { // 注意 while 处理多个 case
        // 64 位输出请用 printf("%lld") to
        scanf("%d %d", &s, &e);
        node* t=(node*)malloc(sizeof(node));
        t->dest=e;
        t->to=adj[s];
        adj[s]=t;
        t=(node*)malloc(sizeof(node));
        t->dest=s;
        t->to=adj[e];
        adj[e]=t;
    }
    printf("%d",bfs(a));
    return 0;
}
发表于 2024-11-21 16:26:08 回复(0)
#include <stdio.h>
#include <stdbool.h>
#define maxlen 2147483646
static bool hasvisit[5000]={false};
static int minlength[5000];
typedef struct{
    int data[50000];
    int top;
}quene;
quene Initque(){
    quene  Q;
    Q.top=0;
    return Q;
}
void putin(quene *q,int data){
    q->data[q->top]=data;
    q->top++;
}
int isempty(quene *q){
    if(q->top<=0) return 1;
    return 0;
}
int depop(quene *q){
    int temp=q->data[0];
    q->top--;
    for(int m=0;m<q->top;m++){
        q->data[m]=q->data[m+1];
    }
    return temp;
}
typedef struct{
    int bian[5000][5000];
    int nbian,n;
}map;
map Init(int n,int m){
    map temp;
    for(int i=0;i<5000;i++){
        for(int j=0;j<5000;j++){
            temp.bian[i][j]=0;
        }
        minlength[i]=maxlen;
    }
    temp.n=n;
    temp.nbian=m;
    return temp;
}
void Insert(map *m,int u,int v){
    m->bian[u-1][v-1]=1;
    m->bian[v-1][u-1]=1;
}
int dfs(map *m,int pre){
    quene q=Initque();
    minlength[pre]=0;
    hasvisit[pre]=true;
    putin(&q,pre);
    while(!isempty(&q)){
        int w=depop(&q);
        for(int i=0;i<5000;i++){
           if(m->bian[w][i]!=0&&hasvisit[i]==false){
            putin(&q,i);
            hasvisit[i]=true;
            int templen=minlength[w]+1;
            minlength[i]=templen<minlength[i] ? templen:minlength[i];
           }
        }
    }
    if(minlength[m->n-1]!=maxlen&&minlength[m->n-1!=0]) return minlength[m->n-1];
    return -1;
}
int main() {
    int a, b;
    scanf("%d %d", &a, &b);
    map m=Init(a, b);
    while(b--){
        int u,v;
        scanf("%d %d",&u,&v);
        Insert(&m, u, v);
    }
    int res=dfs(&m,0);
    printf("%d\n",res);
    return 0;
}
发表于 2024-10-05 19:58:11 回复(0)
BFS可以直接解决。
一开始漏看了这个题是无向图,还在按有向图做,结果怎么都过不了。换成无向图之后就会了

class MainActivity:

    def main(self):
        # Read the data
        n, m = map(int, filter(lambda x: len(x) > 0, input().split(' ')))
        edges = dict()
        for _ in range(m):
            u, v = map(int, filter(lambda x: len(x) > 0, input().split(' ')))
            u -= 1
            v -= 1
            if u in edges:
                edges[u].add(v)
            else:
                edges[u] = {v}
            if v in edges:
                edges[v].add(u)
            else:
                edges[v] = {u}
        # Initialization
        visited = [0] * 5000
        candidates = [0]
        # Traverse
        cnt = 0
        while candidates:
            nextCandidates = []
            for candidate in candidates:
                if candidate == n - 1:
                    print(cnt)
                    return
                visited[candidate] = 1
            for candidate in candidates:
                for nextNode in edges.get(candidate, set()):
                    if not visited[nextNode]:
                        nextCandidates.append(nextNode)
            candidates = nextCandidates
            cnt += 1
        print(-1)


if __name__ == '__main__':
    M = MainActivity()
    M.main()
发表于 2024-09-06 13:31:15 回复(0)
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
//这题使用邻接图过于浪费空间了,所以采用邻接表来存储无向关系
//不管使用邻接表还是邻接图都出现了只有13组用例通过的情况,那这可以确定应该是基本逻辑没有问题,但是边界的处理上还是存在漏洞才会这个样子



//----当输入部分从while(scanf()!=EOF)改为了while(m--)以后就成功通过了
//推测很有可能是因为部分案例不是以EOF结尾的或者说给出的边的数量超过了m,通过控制m以后控制了输入的数量。避免了m条边后面的信息被录入进来干扰了代码。提高了代码的健壮性
#define MAXNUM 5009
typedef struct ArcNode {
    struct VNode* firstvnode;   //顶点链接的第一条边
} arcnode, arcnodelist[MAXNUM];

typedef struct VNode {
    int othervec;   //另一节点
    struct VNode* nextvnode;    //下一条边
} vnode;

typedef struct GRAPH {
    arcnodelist list;
    int n, m;
} graph;            //邻接表信息

typedef struct FIND {
    int val;
    int address;
} Find[MAXNUM];

void buildGraph(int n, int m, graph* G); //创建邻接表
int BFSfind(int n, int now, int findnum, Find find, bool* visited, graph* G);
//广度优先搜索

int main() {
    int n, m;
    scanf("%d %d ", &n, &m);
    graph* G = (graph*)malloc(sizeof(graph));
    G->n = n;
    G->m = m;
    for (int i = 0; i < MAXNUM; i++) {
        G->list[i].firstvnode = NULL;
    }
    int a,b;
    while (m--)
    {
        scanf("%d %d", &a, &b);
        buildGraph(a, b, G);
    }

//----------------初始化邻接表-----------------
    bool visited[MAXNUM] = {0};
    Find find;
    int now, findnum;
    find[0].val = 1;
    find[0].address = 0;
    findnum = 1;
    now = 0;
    visited[1] = true;
    printf("%d", BFSfind(G->n, now, findnum, find, visited, G));
    return 0;
}

int BFSfind(int n, int now, int findnum, Find find, bool* visited, graph* G) {
    while(now<findnum)
    {
        vnode* tmp = G->list[find[now].val].firstvnode;
        while (tmp != NULL) {
        if (visited[tmp->othervec] == 0) {
            visited[tmp->othervec] = true;
            find[findnum].val = tmp->othervec;
            find[findnum].address = find[now].address + 1;
            if (find[findnum].val == n)
                return find[findnum].address;
            findnum++;
        }
        tmp = tmp->nextvnode;
        }
        free(tmp);
        now++;
    }
    return -1; 
}
//这里在创建邻接表的时候,不需要把新的边的关系连在链表的后面,直接加载最开始的部分会更加容易,也省去了很多判断和循环
void buildGraph(int n, int m, graph* G) {  
    vnode* newNode = (vnode*)malloc(sizeof(vnode));  
    newNode->othervec = m;  
    newNode->nextvnode = G->list[n].firstvnode;  
    G->list[n].firstvnode = newNode;  
  
    vnode* newNodeM = (vnode*)malloc(sizeof(vnode));  
    newNodeM->othervec = n;  
    newNodeM->nextvnode = G->list[m].firstvnode;  
    G->list[m].firstvnode = newNodeM;  
}

发表于 2024-08-14 22:56:55 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
private static HashMap<Integer, List<Integer>> map = new HashMap<>();
private static int end = -1;
private static int road = 0;
private static int min = 10000000;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int[] arr1 = getStrArr(in);
end = arr1[0];
min = end;
int m = arr1[1];

for (int i = 0 ; i<=m-1; i++){
int[] arr2 = getStrArr(in);
List<Integer> list = map.get(arr2[0]);
if (Objects.isNull(map.get(arr2[0]))){
list = new ArrayList<>();
list.add(arr2[1]);
map.put(arr2[0], list);
}else{
list.add(arr2[1]);
}
}
bfs(1);
if (min == 1000000){
System.out.print(-1);
}else{
System.out.print(min);
}
}

public static void bfs(int start){
List<Integer> list = map.get(start);
if (list == null && road >= min){
return;
}
for (int n : list){
road++;
if (n != end){
bfs(n);
road--;
}else{
min = Math.min(road, min);
road--;
return;
}
}
}

public static int[] getStrArr(Scanner in){
String s1 = in.nextLine();
String[] arr1 = s1.split(" ");
int[] arr2 = new int[2];
arr2[0] = Integer.valueOf(arr1[0]);
arr2[1] = Integer.valueOf(arr1[1]);
return arr2;
}
}
发表于 2024-05-31 00:09:02 回复(1)
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int n, m;
const int MAXN = 5000;
const int INF = 1e8;
vector<int> graph[MAXN];
bool visited[MAXN] = {false};
int d[MAXN];
void dijkstra(int n, int start) {
    for (int i = 0; i < MAXN; i++)d[i] = INF;
    d[start] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1;
        int MIN = INF;
        for (int j = 0; j < n; j++) {
            if (d[j] < MIN && !visited[j]) {
                u = j;
                MIN = d[j];
            }
        }
        if (u == -1)return;
        visited[u] = true;
        for (int j = 0; j < graph[u].size(); j++) {
            int v = graph[u][j];
            if (!visited[v] && d[u] + 1 < d[v]) {
                d[v] = d[u] + 1;
            }
        }
    }

}
int main() {
    cin >> n >> m;
    int u, v;
    for (int i = 0; i < m; i++) {
        cin >> u >> v;
        graph[u - 1].push_back(v - 1);
        graph[v - 1].push_back(u - 1);
    }
    dijkstra(n, 0);
    if (d[n - 1] == INF) {
        cout << -1;
    } else
        cout << d[n - 1];
}
求解为什么不可以
编辑于 2024-03-13 14:40:41 回复(0)
from collections import deque

def sol(mp, n):
    Q = deque()
    visited = {} #记录访问过的点
    res = 0
    Q.append(0)
    while Q:
        res += 1
        size = len(Q)
        for _ in range(size):
            id = Q.popleft()
            for j in range(len(mp[id])):
                if mp[id][j] == n - 1:
                    return res
                if mp[id][j] not in visited:
                    Q.append(mp[id][j])
                    visited[mp[id][j]] = 1
    return -1


n, m = map(int, input().split())
mp = [[] for _ in range(2 * n)] #邻接矩阵,预留了较大的空间
for _ in range(m):
    x1, x2 = map(int, input().split())
    mp[x1 - 1].append(x2 - 1)
    mp[x2 - 1].append(x1 - 1)
print(sol(mp, n))



编辑于 2024-03-12 20:09:44 回复(0)
c语言,主要想真的节省空间要费老大劲了,我真的不会,还是邻接矩阵+广度优先的常规方法,或者要么迪杰斯特拉当成一个带权图
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
//邻接矩阵 + 广度优先搜索

typedef struct graph{
    int datas[5000][5000]; 
}graph;

typedef struct node{
    int point;
    int layer;
}node;
typedef struct queue{
    node datas[5001];
    int front;
    int rear;
}queue;
void init_queue(queue* q){
    q->front = 0;
    q->rear = 0;
}
int empty_queue(queue* q){
    if(q->front == q->rear){
        return 1;
    } else {
        return 0;
    }
}
int full_queue(queue* q){
    if(q->front == ((q->rear+1) % 5001)){
        return 1;
    } else {
        return 0;
    }
}
int in_queue(queue* q,int point,int layer){
    if(!full_queue(q)){
        q->datas[q->rear].point = point;
        q->datas[q->rear].layer = layer;
        q->rear = (q->rear + 1)%5001;
        return 1;
    } else {
        return 0;
    }
}

int de_queue(queue* q,node** node){
    if(!empty_queue(q)){
        *node = &q->datas[q->front];
        q->front = (q->front+1)%5001;
        return 1;
    } else {
        return 0;
    }
}

void init_graph(graph* g){
    memset(g->datas, 0, sizeof(g->datas));
}

int add_edge(graph* g,int start,int end){
    g->datas[start-1][end-1] = 1;
    g->datas[end-1][start-1] = 1;
    return 1;
}

int bfs(graph* g,int start,int end){
    bool visited[5001];
    memset(visited, 0, sizeof(visited));
    queue q;
    init_queue(&q);
    in_queue(&q, start,0);

    int flag = 0;
    node* node;
    while(!empty_queue(&q)){
        de_queue(&q, &node);
        visited[node->point] = true;
        if(g->datas[node->point-1][end-1] == 1){
            flag = 1;
            break;
        }
        for(int i = 0; i < 5000;i++){
            if(g->datas[node->point-1][i] == 1 && !visited[i+1]){
                in_queue(&q,i+1,node->layer+1);
            }
        }
    }
    if(flag == 1){
        return node->layer+1;
    } else {
        return -1;
    }
}

int main() {
    int n,m,start,end;
    scanf("%d%d",&n,&m);
    graph g;
    init_graph(&g);
    for(int i = 0; i < m;i++){
        scanf("%d%d",&start,&end);
        add_edge(&g, start,end);
    }
    int result = bfs(&g, 1, n);
    printf("%d\n",result);
    return 0;
}



发表于 2024-02-19 17:22:34 回复(0)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 5e4+10;
int h[N],d[N],q[N];
int e[2*N],ne[2*N],idx;
int n,m;

void add(int a,int b)
{
    e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}

int bfs()
{
    memset(d,-1,sizeof d);
    int hh = 0,tt = 0;
    d[1] = 0;
    q[0] = 1;

    while(hh<=tt)
    {
        int t = q[hh++];
        for(int i = h[t];i != -1;i = ne[i])
        {
            int j = e[i];
            if(d[j] == -1)
            {
                d[j] = d[t] + 1;
                q[++tt] = j;
            }
        }
    }
    return d[n];
}

int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof h);
    for(int i = 0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        add(u,v);add(v,u);
    }
    cout << bfs() << endl;
    return 0;
}
发表于 2023-11-25 09:33:42 回复(0)
#include<bits/stdc++.h>
using namespace std;
typedef struct{
    int id;
    int sum;
}node;
int g[5001][5001];
bool vis[5001];
queue<node>q;
void bfs(int s,int e){
    node first;
    first.id=s;
    first.sum=0;
    q.push(first);
    vis[s]=true;
    while(!q.empty()){
        node node1=q.front();
        if(node1.id==e){
            cout<<node1.sum;
            break;
        }
        q.pop();
        for(int i=1;i<=5000;i++){
            if(vis[i]==false&&g[node1.id][i]!=0){
                node it;
                it.id=i;
                it.sum=node1.sum+1;
                q.push(it);
                vis[i]=true;
            }
        }
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    int x,y;
    for(int i=0;i<m;i++){
        cin>>x>>y;
        g[x][y]=g[y][x]=1;

    }
    bfs(1,n);
    if(q.front().id!=n)
    cout<<-1;
    return 0;
    
}

发表于 2023-08-09 15:50:56 回复(0)
想问各位大佬,这题是用SPFA(松弛)是不能通过的是吗?
#include<iostream>
#include <queue>
#include<vector>
#include<climits>

using namespace std;

// 以下是spfa的实现
void SPFA(int Node_n, vector<int>& distance, const vector<vector<int>>& graph){
    queue<int> Qgraph;
    vector<bool> NodeState(Node_n + 1, false);
    
    Qgraph.push(1);  // 先第一个点入队
    distance[1] = 0; // 第一点到第一点的距离为0
    NodeState[1] = true; // 标记第一点入队
    while(!Qgraph.empty()){
        int Node = Qgraph.front();
        Qgraph.pop();
        NodeState[Node] = false;
        for(int i = 1; i <= graph[Node].size(); i++){ // 更新维护路径距离表
             if(graph[Node][i] != INT_MAX  && distance[i] > distance[Node] + graph[Node][i]){
                distance[i] = distance[Node] + graph[Node][i];
                if(!NodeState[i]){
                    Qgraph.push(i);
                    NodeState[i] = true;
                }
             }
        }
    }

}

int main(){
    int Node_n = 10, Edge_m = 10;
    cin >> Node_n >> Edge_m;
    // 先把图存起来
    vector<vector<int>> graph(2*Edge_m, vector<int>(2*Edge_m, INT_MAX));
    // 查了半天,请记得vector的嵌套用法,谢谢你。
    vector<int> distance(Edge_m+1, INT_MAX);
    while(Edge_m--){
        int u = 0, v = 0;
        cin >> u >> v;
        graph[u][v] = 1;  // 邻接表,表示u到v的距离为1
        graph[v][u] = 1; // 注意为无向图,需要关于主对角线对称,因此两边都需要存储相等值
    }
    SPFA(Node_n, distance, graph);
    if(distance[Node_n] != INT_MAX){
        cout << distance[Node_n] << endl;
    }else {
        cout << -1 << endl;
    }
    return 0;
}

发表于 2023-08-03 10:48:52 回复(0)
#include <stdio.h>
#include <stdlib.h>

#define MAX 5001

int** new_map(int n){
    int** res=(int**)malloc((n+1)*sizeof(int*));
    for(int i=0;i<=n;i++){
        res[i]=(int*)malloc((n+1)*sizeof(int));
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            res[i][j]=-1;
        }
    }
    return res;
}

int main() {
    int n, m;
    scanf("%d %d",&n,&m);
    int** map=new_map(MAX);
    for (int i=0; i<m ; i++) {
        int u,v;
        scanf("%d %d",&u,&v);
        map[u][v]=1;
        map[v][u]=1;
    }

    //初始化队列
    int* queue=(int*)calloc(MAX, sizeof(int));
    int head=0,tail=0;
    //初始化访问数组,0未访问,1已访问
    int* visited=(int*)calloc(MAX, sizeof(int));
    //初始化计数数组
    int* count=(int*)calloc(MAX, sizeof(int));

    int size=n+1;
    //1号节点入队
    queue[tail]=1;
    tail=(tail+1)%size;
    visited[1]=1;
    count[1]=0;
    //当队列不为空时
    while (head!=tail) {
        //出队一个元素
        int p=queue[head];
        head=(head+1)%size;
        //遍历p能到达的所有未被访问的点
        for(int i=1;i<MAX;i++){
            if(visited[i]==0 && map[p][i]!=-1){
                //i入队,并标记为访问过
                queue[tail]=i;
                tail=(tail+1)%size;
                visited[i]=1;
                //更新i对应计数
                count[i]=count[p]+1;
            }
        }
    }

    if(visited[n]==0){
        printf("-1");
    }else {
        printf("%d",count[n]);
    }

    return 0;
}

发表于 2023-07-21 11:45:01 回复(0)
题目描述前后不一致,容易产生误解。
m是边数,n是目标节点,而不是节点总数。节点总数是5000。
---------------------------------------------------------------------------------
标记数组+广度优先遍历搜索目标节点。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
bool find_path(vector<vector<int>>& matrix, 
        int& num_vertexs, int target_vertex, int& res) {
    queue<int> q;
    // 标记数组,访问过的点置为1.
    vector<bool> visit(num_vertexs + 1, false);
    visit[0] = true;
    visit[1] = true;
    q.push(1);
    while (!q.empty()) {
        int q_size = q.size();
        // 每次访问到一个新的深度时递增,最终结果比预期大1
        res++;
        while (q_size--) {
            int curr = q.front();
            q.pop();
            if (curr == target_vertex) {
                return true;
            }
            for (int i = 0; i < matrix[curr].size(); i++) {
                // 只把没有访问过的节点加入队列,并且标记节点
                if (!visit[matrix[curr][i]]) {
                    q.push(matrix[curr][i]);
                    visit[matrix[curr][i]] = true;
                }
            }
        }
    }
    return false;
}
int main() {
    int num_edges;
    int target_vertex;
    int num_vertexs = 5000;
    cin >> target_vertex >> num_edges;
    vector<vector<int>> matrix(num_vertexs + 1);
    int start, end;
    for (int i = 0; i < num_edges; i++) {
        cin >> start >> end;
        matrix[start].push_back(end);
        matrix[end].push_back(start);
    }
    int res = 0;
    bool result = find_path(matrix, num_vertexs, target_vertex, res);
    res = result ? res - 1 : -1;
    cout << res << endl;
    return 0;
}


发表于 2023-05-06 23:16:19 回复(0)