1. 程式人生 > >資料結構與演算法題目集(中文) 7-6 列出連通集

資料結構與演算法題目集(中文) 7-6 列出連通集

7-6 列出連通集(25 分)提問

給定一個有N個頂點和E條邊的無向圖,請用DFS和BFS分別列出其所有的連通集。假設頂點從0到N−1編號。進行搜尋時,假設我們總是從編號最小的頂點出發,按編號遞增的順序訪問鄰接點。

輸入格式:

輸入第1行給出2個整數N(0<N≤10)和E,分別是圖的頂點數和邊數。隨後E行,每行給出一條邊的兩個端點。每行中的數字之間用1空格分隔。

輸出格式:

按照"{ v​1​​ v​2​​ ... v​k​​ }"的格式,每行輸出一個連通集。先輸出DFS的結果,再輸出BFS的結果。

輸入樣例:

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

輸出樣例:

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

一開始用結構體做的,然後提交發現只有唯一的答案,發現事情並不簡單 ,然後看了別人的儲存方式方才恍然大悟。以後要好好學習資料結構啊。。。

程式碼如下:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int n,e;
int Map[15];
int road[15];
int num;
int locc[15][15];
void dfs (int c)
{
     road[num++]=c;
     Map[c]=1;
    for (int i=0;i<n;i++)
    {
        if(locc[c][i]==1&&!Map[i])
        {
            dfs (i);
        }
    }
}
void bfs (int c)
{
    queue <int> q;
    q.push(c);
    int temp;
    while (!q.empty())
    {
        temp=q.front();
        q.pop();
       for (int i=0;i<n;i++)
      {
        if(locc[temp][i]==1&&!Map[i])
        {
            road[num++]=i;
            Map[i]=1;
            q.push(i);
        }
      }
    }
}
int main()
{
    scanf("%d%d",&n,&e);
    memset (Map,0,sizeof(Map));
    memset (locc,0,sizeof(locc));
    for (int i=0;i<e;i++)
    {
            int x,y;
            scanf("%d%d",&x,&y);
            locc[x][y]=locc[y][x]=1;
    }
    for (int i=0;i<n;i++)
    {
        if(!Map[i])
        {
            num=0;
            dfs (i);
            if(num)
            {
             printf("{ ");
            for (int i=0;i<num;i++)
                printf("%d ",road[i]);
             printf("}\n");

            }
        }
    }
    memset (Map,0,sizeof(Map));
    for (int i=0;i<n;i++)
    {
        if(!Map[i])
        {
            num=0;
            road[num++]=i;
            Map[i]=1;
            bfs (i);
             //sort (road,road+num);
            if(num)
            {
             printf("{ ");
            for (int i=0;i<num;i++)
                printf("%d ",road[i]);
             printf("}\n");

            }
        }
    }
    return 0;
}

其實可以直接printf的,建了個數組花裡胡哨。。。

第二次做的程式碼如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn=15;
int n,e;
int edge[maxn][maxn];
int vis[maxn];
vector <int> re;
void init()
{
    memset (edge,0,sizeof(edge));
}
void dfs (int x)
{
    vis[x]=1;
    re.push_back(x);
    for (int i=0;i<n;i++)
    {
        if(edge[x][i]&&!vis[i])
        {
            dfs(i);
        }
    }
}
void bfs (int s)
{
    queue<int>q;
    vis[s]=1;
    re.push_back(s);
    q.push(s);
    while (!q.empty())
    {
        int now=q.front();
        q.pop();
        for (int i=0;i<n;i++)
        {
            if(edge[now][i]&&!vis[i])
            {
                vis[i]=1;
                q.push(i);
                re.push_back(i);
            }
        }
    }
}
int main()
{
    init();
    scanf("%d%d",&n,&e);
    for (int i=0;i<e;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        edge[x][y]=edge[y][x]=1;
    }
    memset (vis,0,sizeof(vis));
    for (int i=0;i<n;i++)
    {
        if(!vis[i])
        {
            re.clear();
            dfs(i);
            printf("{ ");
            for (int i=0;i<re.size();i++)
                printf("%d ",re[i]);
            printf("}\n");
        }
    }
    memset (vis,0,sizeof(vis));
    for (int i=0;i<n;i++)
    {
        if(!vis[i])
        {
            re.clear();
            bfs(i);
            printf("{ ");
            for (int i=0;i<re.size();i++)
                printf("%d ",re[i]);
            printf("}\n");
        }
    }
    return 0;
}