首页 > 试题广场 >

【模板】单源最短路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号点。 
#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 <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)