C - 数据结构实验之图论三:判断可达性
Description
在古老的魔兽传说中,有两个军团,一个叫天灾,一个叫近卫。在他们所在的地域,有n个隘口,编号为1…n,某些隘口之间是有通道连接的。其中近卫军团在1号隘口,天灾军团在n号隘口。某一天,天灾军团的领袖巫妖王决定派兵攻打近卫军团,天灾军团的部队如此庞大,甚至可以填江过河。但是巫妖王不想付出不必要的代价,他想知道在不修建任何通道的前提下,部队是否可以通过隘口及其相关通道到达近卫军团展开攻击。由于n的值比较大(n<=1000),于是巫妖王找到了擅长编程的你 =_=,请你帮他解决这个问题,否则就把你吃掉变成他的魔法。为了拯救自己,赶紧想办法吧。

Input
输入包含多组,每组格式如下。

第一行包含两个整数n,m(分别代表n个隘口,这些隘口之间有m个通道)。

下面m行每行包含两个整数a,b;表示从a出发有一条通道到达b隘口(注意:通道是单向的)。

Output
如果天灾军团可以不修建任何通道就到达1号隘口,那么输出YES,否则输出NO。

Sample
Input
2 1
1 2
2 1
2 1
Output
NO
YES

其实就是判断是否是连通图

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//数组太大,不能用结构体和局部变量


int vex[1010];//顶点数组
int arc[1010][1010];//通道//边
int n;//顶点(隘口)


int visited[1010];//访问数组
int flag;//判断标识

//其实起始顶点是 n,即下标为(n-1),顶点的值比其下标大 1
//此题考查的就是看图是否为连通图
void DFS(int i) {

    visited[i] = 1; //访问标记

    if(vex[i] == 1) {
        flag = 1; //如果成功访问到 1,则证明能连通
    }
    /*
    从图中某个顶点i(顶点下标)出发,访问此顶点,然后从i的未被访问的邻接点出发深度优先遍历图,直至
    图中所有和i有路径相通的顶点都被访问到。事实上,我们这里讲到的是连通图,对于非连
    通图,只需要对它的连通分量分别进行深度优先遍历,即在先前一个顶点进行一次深度优
    先遍历后,若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复
    上述过程,直至图中所有顶点都被访问到为止。
    */
    for(int j = 0; j < n; j++) {
        if(arc[i][j] == 1 && visited[j] == 0) {
            DFS(j);
        }
    }
}

int main() {
    int m;//边数(通道)
    int a, b; //表示从a出发有一条通道到达b隘口(注意:通道是单向的//有向图)。

    while(scanf("%d%d", &n, &m) != EOF) {
        flag = 0;
        //初始化访问数组
        memset(visited, 0, sizeof(visited));

        //给定点给数组赋值
        for(int i = 0; i < n; i++) {
            vex[i] = i + 1;
        }

        memset(arc,0,sizeof(arc));

        //构造通道//有向图,所以不能用对称矩阵
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &a, &b);
            arc[a-1][b-1] = 1;
        }

        DFS(n - 1);
        if(flag == 1) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }
    return 0;
}

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐