路径判断(可用dfs||floyed||并查集)

7-1 路径判断 (20 分)

给定一个有N个顶点和E条边的无向图,请判断给定的两个顶点之间是否有路径存在。 假设顶点从0到N−1编号。

输入格式:

输入第1行给出2个整数N(0

随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

最后一行给出两个顶点编号i,j(0≤i,j

输出格式:

如果i和j之间存在路径,则输出"There is a path between i and j.",

否则输出"There is no path between i and j."。

输入样例1:

7 6
0 1
2 3
1 4
0 2
1 3
5 6
0 3

输出样例1:

There is a path between 0 and 3.

输入样例2:

7 6
0 1
2 3
1 4
0 2
1 3
5 6
0 6

输出样例2:

There is no path between 0 and 6.

 //法1:图的基本操作(dfs)
#include
int vis[15];
int p,q,flag=0;
typedef struct graph
{
    int arcs[15][15];
    int vexnum,arcnum;
}Graph;
void dfs(Graph G,int p)
{
    vis[p]=1;
    for(int k=0;k     {
        if(G.arcs[p][k]&&k==q&&!vis[k])//只要在遍历起点(p)的邻接点的时候每次判断一下是不是要找的终点(q)就行了
        {
            flag=1;
        }
        else if(G.arcs[p][k]&&!vis[k])
        {
            dfs(G,k);
        }
    }
}
int main()
{
    Graph G;
    scanf("%d%d",&G.vexnum,&G.arcnum);
    for(int i=0;i     {
        for(int j=0;j         {
            G.arcs[i][j]=0;//首先全都初始化为0
            G.arcs[j][i]=0;
        }
    }
    for(int i=0;i     {
        G.arcs[i][i]=1;//每个点肯定能到其本身
    }
    int v1,v2;
    for(int i=0;i     {
        scanf("%d%d",&v1,&v2);
        G.arcs[v1][v2]=1;//有路径的两点记为1
        G.arcs[v2][v1]=1;
    }
    scanf("%d%d",&p,&q);
    dfs(G,p);
    if(G.vexnum==1)//就一个顶点,那这个点肯定能到他本身
    {
        printf("There is a path between %d and %d.\n",p,q);
    }
    else if(flag)
    {
        printf("There is a path between %d and %d.\n",p,q);
    }
    else{
        printf("There is no path between %d and %d.\n",p,q);
    }
    return 0;
}

 

//法2:弗洛伊德(floyed)
#include
int n,e,p,q,a[15][15];
void floyed()//通过一个中转点(k)把有路径的两点直接连接起来
{
    for(int i=0;i     {
        a[i][i]=1;//每个点肯定能到其本身
    }
    for(int i=0;i     {
        for(int j=0;j         {
            for(int k=0;k             {
                if(a[i][j]&&a[j][k])
                {
                    a[i][k]=1;//i能到j同时j又能到k,那么i就能通过j到k了(就可以直接把k和i连起来了),全都这样操作后,两点之间能否到达就可以直接判断了
                }
            }
        }
    }
}
int main()
{
   scanf("%d%d",&n,&e);
   for(int i=0;i    {
       int z,x;
       scanf("%d%d",&z,&x);
       a[z][x]=1;
       a[x][z]=1;
   }
   floyed();
   scanf("%d%d",&p,&q);
   if(n==1)
   {
       printf("There is a path between %d and %d.\n",p,q);
   }
   else if(a[p][q])
   {
       printf("There is a path between %d and %d.\n",p,q);
   }
   else{
    printf("There is no path between %d and %d.\n",p,q);
   }
   return 0;
}

 

//法3:并查集
#include
int pre[100],n,e;
void init()
{
    for(int i=0;i<=n;i++)
    {
        pre[i]=i;
    }
}
int getroot(int a)
{
    if(pre[a]!=a)
    {
        return pre[a]=getroot(pre[a]);
    }
    else{
        return pre[a];
    }
}
void mergeit(int x,int y)
{
    int p1=getroot(x);
    int p2=getroot(y);
    if(p1==p2)
    {
        return;
    }
    else{
        pre[p2]=p1;
    }
}
int main()
{
    scanf("%d%d",&n,&e);
    init();
    for(int i=0;i     {
        int u,v;
        scanf("%d%d",&u,&v);
        mergeit(u,v);
    }
    int p,q;
    scanf("%d%d",&p,&q);
    if(n==1)
    {
        printf("There is a path between %d and %d.\n",p,q);
    }
    else if(getroot(p)==getroot(q))//判断p,q两点的根节点是否相同,如果根节点相同,则这两点间有路径
    {
        printf("There is a path between %d and %d.\n",p,q);
    }
    else{
        printf("There is no path between %d and %d.\n",p,q);
    }
}

你可能感兴趣的:(路径判断(可用dfs||floyed||并查集))