数据结构第11周 :(图的遍历及连通性 + 犯罪团伙 + 图形窗口问题 + 最小生成树的权值之和 + Jungle Roads )

这篇具有很好参考价值的文章主要介绍了数据结构第11周 :(图的遍历及连通性 + 犯罪团伙 + 图形窗口问题 + 最小生成树的权值之和 + Jungle Roads )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

图的遍历及连通性

【问题描述】
根据输入的图的邻接矩阵A,判断此图的连通分量的个数。请使用邻接矩阵的存储结构创建图的存储,并采用BFS优先遍历算法实现,否则不得分。
【输入形式】
第一行为图的结点个数n,之后的n行为邻接矩阵的内容,每行n个数表示。其中A[i][j]=1表示两个结点邻接,而A[i][j]=0表示两个结点无邻接关系。
【输出形式】
输出此图连通分量的个数。
【样例输入】
5
0 1 1 0 0
1 0 1 0 0
1 1 0 0 0
0 0 0 0 1
0 0 0 1 0
【样例输出】
2
【样例说明】
邻接矩阵中对角线上的元素都用0表示。(单个独立结点,即与其它结点都没有边连接,也算一个连通分量)

#include<iostream>
#define N 100
#include<queue>
using namespace std;
int matrix[N][N];

void bfs(int node, int matrix[N][N], int visited[N], int limit)
{
    queue<int> s;
    s.push(node);
    visited[node] = 1;
    while(!s.empty())
    {
        node = s.front();
        s.pop();
        int j = 0;
        for(j = 1; j < limit; j ++)
        {
            if(matrix[node][j] == 1 && visited[j] == 0)
            {
                s.push(j);
                visited[j] = 1;
            }
        }
    }
}

int main()
{
    int node;
    cin>>node;
    int i = 0;
    int j = 0;
    for(i = 1; i < node + 1; i ++) //创建邻接矩阵,从一号位开始存放
    {
        for(j = 1; j < node + 1; j++)
            cin>>matrix[i][j];
    }
    int res = 0;
    int visited[node + 1];
    for(i = 0; i < node + 1; i ++) visited[i] = 0;//初始化访问数组
    for(i = 1; i < node + 1; i ++)
    {
        if(visited[i] == 0)
        {
            bfs(i, &matrix[0], visited, node + 1); //二维数组传第一行的地址
            res ++;
        }
    }
    cout<<res;
    return 0;
}

犯罪团伙

【题目描述】

此题必须采用邻接表的存储结构,建立图的存储,然后采用DFS遍历实现求解。否则不给分。

警察抓到了 n 个罪犯,警察根据经验知道他们属于不同的犯罪团伙,却不能判断有多少个团伙,但通过警察的审讯,知道其中的一些罪犯之间相互认识,已知同一犯罪团伙的成员之间直接或间接认识。有可能一个犯罪团伙只有一个人。请你根据已知罪犯之间的关系,确定犯罪团伙的数量。已知罪犯的编号从 1 至 n。

【输入】

第一行:n(<=1000,罪犯数量),第二行:m(<5000,关系数量)以下若干行:每行两个数:I 和 j,中间一个空格隔开,表示罪犯 i 和罪犯 j 相互认识。

【输出】

一个整数,犯罪团伙的数量。

【样例输入】

11

8

1 2

4 3

5 4

1 3

5 6

7 10

5 10

8 9

【输出】

3

#include<iostream>
#define N 50
using namespace std;

int matrix[N][N];

void dfs(int human, int visited[N], int limit)
{
    visited[human] = 1;
    int j = 1;
    for(; j < limit; j ++)
    {
        if(matrix[human][j] == 1 && visited[j] == 0)
            dfs(j, visited, limit);
    }
}

int main()
{
    int human; //罪犯数量
    int relation; // 关系数量
    cin>>human>>relation;
    int i = 0;
    int j = 0;
    for(i = 0; i < N; i ++)
    {
        for(j = 0; j < N; j ++)
            matrix[i][j] = 0;
    }
    while(relation --)
    {
        int i, j;
        cin>>i>>j;
        matrix[i][j] = 1;
        matrix[j][i] = 1;
    }
    int visited[human + 1];
    for(i = 0; i < human + 1; i ++) visited[i] = 0;
    int res = 0;
    for(i = 1; i < human + 1; i++)
    {
        if(visited[i] == 0)
        {
            dfs(i, visited, human + 1);
            res ++;
        }
    }
    cout<<res;
    return 0;
}

图形窗口问题

【问题描述】

在某图形操作系统中,有N个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。

当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。

现在我们希望你写一个程序模拟点击窗口的过程。

【输入形式】

输入的第一行有两个正整数,即N和M。(1<=N<=10,1<=M<=10)接下来N行按照从最下层到最顶层的顺序给出N个窗口的位置。每行包含四个非负整数x1,y1,x2,y2,表示该窗口的一对顶点坐标分别为(x1,y1)和(x2,y2)。保证x1<x2,y1<y2。

接下来M行每行包含两个非负整数x,y,表示一次鼠标点击的坐标。题目中涉及到的所有点和矩形的顶点的x,y坐标分别不超过2559和1439。

【输出形式】

输出包括M行,每一行表示一次鼠标点击的结果。如果该次鼠标点击选择了一个窗口,则输出这个窗口的编号(窗口按照输入中的顺序从1编号到N);如果没有,则输出"IGNORED"(不含双引号)。

【样例输入】

3 4

0 0 4 4

1 1 5 5

2 2 6 6

1 1

0 0

4 4

0 5

【样例输出】

2

1

1

IGNORED

【样例说明】

第一次点击的位置同时属于第1和第2个窗口,但是由于第2个窗口在上面,它被选择并且被置于顶层。

第二次点击的位置只属于第1个窗口,因此该次点击选择了此窗口并将其置于顶层。现在的三个窗口的层次关系与初始状态恰好相反了。第三次点击的位置同时属于三个窗口的范围,但是由于现在第1个窗口处于顶层,它被选择。

最后点击的(0,5)不属于任何窗口。

【备注】2014年3月CCF-CSP考试真题第2题

#include<iostream>
#define N 20
using namespace std;

typedef struct
{
    int x;
    int y;
}point;

typedef struct
{
    point p1;
    point p2;
    int num;
}windows;

int main()
{
    windows w[N];
    int WindowsNum = 0;
    cin>>WindowsNum;
    int ClickNum = 0;
    cin>>ClickNum;
    int i = 1;
    while(1)
    {
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        point a, b;
        a.x = x1;
        a.y = y1;
        b.x = x2;
        b.y = y2;
        windows p;
        p.p1 = a;
        p.p2 = b;
        p.num = i;
        w[i] = p;
        if(i == WindowsNum) break;
        i ++;
    }
    while(ClickNum --)
    {
        int x, y;
        cin>>x>>y;
        int pos = 0;
        for(pos = WindowsNum; pos > 0; pos --)
        {
            if(x >= w[pos].p1.x && y >= w[pos].p1.y && x <= w[pos].p2.x && y <= w[pos].p2.y)
            {
                cout<<w[pos].num<<endl;
                int i = 0;
                windows temp = w[pos];
                for(i = pos; i < WindowsNum; i ++)
                {
                    w[i] = w[i + 1];
                }
                w[WindowsNum] = temp;
                break;
            }
        }
        if(pos == 0) cout<<"IGNORED"<<endl;
    }
    return 0;
}

最小生成树的权值之和

【问题描述】
已知含有n个顶点的带权连通无向图,采用邻接矩阵存储,邻接矩阵以三元组的形式给出,只给出不包括主对角线元素在内的下三角形部分的元素,且不包括不相邻的顶点对。请采用Prim算法,求该连通图从1号顶点出发的最小生成树的权值之和。
【输入形式】
第一行给出结点个数n和三元组的个数count,以下每行给出一个三元组,数之间用空格隔开。(注意这里顶点的序号是从1到n,而不是0到n-1,程序里要小心!)
【输出形式】
求解的最小生成树的各条边、边的权值之和
【样例输入】
5 8
2 1 7
3 1 6
3 2 8
4 1 9
4 2 4
4 3 6
5 2 4
5 4 2
【样例输出】

1-3:6
3-4:6
4-5:2
4-2:4
18

【样例说明】
权值是正整数,可能很大,但不需要考虑整型溢出问题

#include<iostream>
#define N 50
#define Max 999999
using namespace std;

int R[N][N];
typedef struct
{
    int adjvex;
    int loweight;
    int flag;
}Closedge;

int Min(Closedge * MTree, int limit)
{
    int min = 99999;
    int i = 0;
    int res = 0;
    for(i = 1; i <= limit; i ++)
    {
        if(MTree[i].loweight < min && MTree[i].flag == 1)
        {
            min = MTree[i].loweight;
            res = i;
        }
    }
    return res;
}

void Prim(int limit)
{
    int sum = 0;
    Closedge MTree[limit + 1];
    int i = 0;
    for(i = 1; i <= limit; i ++) //初始化
    {
        if(i != 1)
            MTree[i].adjvex = 1;
        MTree[i].flag = 1;
        MTree[i].loweight = R[1][i];
    }
    for(i = 2; i <= limit; i ++)
    {
        int MinId = Min(MTree, limit);
        cout<<MTree[MinId].adjvex<<'-'<<MinId<<':'<<MTree[MinId].loweight<<endl;
        sum += MTree[MinId].loweight;
        MTree[MinId].flag = 0;
        int j = 0;
        for(j = 2; j <= limit; j ++)
        {
            if(R[MinId][j] < MTree[j].loweight)
            {
                MTree[j].loweight = R[MinId][j];
                MTree[j].adjvex = MinId;
            }
        }
    }
    cout<<sum;
}

int main()
{
    int NodeNum;
    int RelationNum;
    cin>>NodeNum>>RelationNum;
    int i = 0;
    int j = 0;
    for(i = 1; i <= NodeNum; i++)
    {
        for(j = 1; j <= NodeNum; j ++)
        {
            R[i][j] = Max;
        }
    }
    while(RelationNum --)
    {
        int i, j, k;
        cin>>i>>j>>k;
        R[i][j] = k;
        R[j][i] = k;
    }
    Prim(NodeNum);
    return 0;
}

Jungle Roads

请用kruskal算法编程实现下面的问题。
The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain. The Council of Elders must choose to stop maintaining some roads. The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them. Of course there needs to be some way to get between all the villages on maintained roads, even if the route is not as short as before. The Chief Elder would like to tell the Council of Elders what would be the smallest amount they could spend in aacms per month to maintain roads that would connect all the villages. The villages are labeled A through I in the maps above. The map on the right shows the roads that could be maintained most cheaply, for 216 aacms per month. Your task is to write a program that will solve such problems.

Input

The input consists of one to 100 data sets, followed by a final line containing only 0. Each data set starts with a line containing only a number n, which is the number of villages, 1 < n < 27, and the villages are labeled with the first n letters of the alphabet, capitalized. Each data set is completed with n-1 lines that start with village labels in alphabetical order. There is no line for the last village. Each line for a village starts with the village label followed by a number, k, of roads from this village to villages with labels later in the alphabet. If k is greater than 0, the line continues with data for each of the k roads. The data for each road is the village label for the other end of the road followed by the monthly maintenance cost in aacms for the road. Maintenance costs will be positive integers less than 100. All data fields in the row are separated by single blanks. The road network will always allow travel between all the villages. The network will never have more than 75 roads. No village will have more than 15 roads going to other villages (before or after in the alphabet). In the sample input below, the first data set goes with the map above.

Output

The output is one integer per line for each data set: the minimum cost in aacms per month to maintain a road system that connect all the villages. Caution: A brute force solution that examines every possible set of roads will not finish within the one minute time limit.文章来源地址https://www.toymoban.com/news/detail-461330.html

#include<iostream>
#define N 100
using namespace std;

typedef struct
{
    char node1;
    char node2;
    int weight;
}MTree;

int parent[N];

void Init(int limit)
{
    int i;
    for(i = 0; i <= limit; i ++)
    {
        parent[i] = i;
    }
}

int find(char a)
{
    int m = int(a) - 65;
    int root = int(a) - 65;
    while(root != parent[root]) root = parent[root];
    while(m != root)
    {
        int t = parent[m];
        parent[m] = root;
        m = t;
    }
    return root;
}

void unite(char a, char b)
{
    int m = find(a);
    int n = find(b);
    parent[n] = m;

}

void Sort(MTree tree[N], int limit)
{
    int i, j;
    for(i = 0; i <= limit; i ++)
    {
        int min = tree[i].weight;
        int minid = i;
        for(j = i + 1; j <= limit; j ++)
        {
            if(tree[j].weight < min)
            {
                min = tree[j].weight;
                minid = j;
            }
        }
        if(minid != i)
        {
            MTree temp = tree[i];
            tree[i] = tree[minid];
            tree[minid] = temp;
        }
    }
}

void Kruskal(MTree tree[N], int limit)
{
    int res = 0;
    int i = 0;
    for(i = 0; i <= limit; i ++)
    {
        if(find(tree[i].node1) != find(tree[i].node2))
        {
            unite(tree[i].node1, tree[i].node2);
            res += tree[i].weight;
            //cout<<tree[i].weight<<endl;
        }
    }
    cout<<res<<endl;
}

int main()
{
    MTree tree[N];
    int NodeNum;
    cin>>NodeNum;
    int i = 1;
    int count = -1;
    while(1)
    {
        char a1;
        cin>>a1;
        int RelationNum;
        cin>>RelationNum;
        while(RelationNum --)
        {
            count ++;
            char a2;
            cin>>a2;
            int r;
            cin>>r;
            tree[count].node1 = a1;
            tree[count].node2 = a2;
            tree[count].weight = r;
        }
        if(i == NodeNum - 1) break;
        i ++;
    }
    Init(count);
    Sort(tree, count);
    /*for(i = 0; i <= count; i ++)
    {
        cout<<tree[i].node1<<" "<<tree[i].node2<<" "<<tree[i].weight<<endl;
    }
    cout<<endl;*/
    Kruskal(tree, count);
    return 0;
}

到了这里,关于数据结构第11周 :(图的遍历及连通性 + 犯罪团伙 + 图形窗口问题 + 最小生成树的权值之和 + Jungle Roads )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】图的存储与遍历

    图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E) 在有向图中,顶点对x, y是有序的,顶点对x,y称为顶点x到顶点y的一条边(弧),x, y和y, x是两条不同的边。 在无向图中,顶点对(x, y)是无序的,顶点对(x,y)称为顶点x和顶点y相关联的一条边,这条边没有特定方向,

    2024年02月22日
    浏览(34)
  • 【数据结构】图的广度优先遍历

    广度优先遍历,类似于树的层次遍历,又是熟悉的队列实现。首先将第一个顶点添加到队列中,然后讲该顶点的所有邻接顶点都加入队列中,再将该顶点输出。如此重复直到遍历完整个图。 Q:队列,用于存放顶点。 front,rear:队头和队尾指针,用于入队和出队。 p:工作指针,用

    2024年02月05日
    浏览(35)
  • 【数据结构】图的定义,存储,遍历

    🎊专栏【数据结构】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Dream It Possible】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🍔前言 🎁图的定义   🏳️‍🌈有向完全图 🏳️‍🌈无向完全图 🎁存储结构 🏳️‍🌈邻接矩阵  🎈代码

    2024年02月06日
    浏览(66)
  • 数据结构 第六章 图——图的遍历

    在前面我们知道,树是一种非线性结构,为了方便它在计算机中的存储,对树进行遍历使它线性化。 而图同样也是一种非线性结构,但是图又是一种不同于树的多对多结构,所以在前面我们将其转换为了多个一对多的结构来描述它的存储结构。 图的遍历同树类似,也是从某

    2024年02月08日
    浏览(35)
  • 大话数据结构-图的深度优先遍历和广度优先遍历

      图的遍历分为深度优先遍历和广度优先遍历两种。   深度优先遍历(Depth First Search),也称为深度优先搜索,简称DFS,深度优先遍历,是指从某一个顶点开始,按照一定的规则,访问并记录下一个未访问顶点。对于非连通图,则是按连通分量,采用同一规则进行深度优

    2024年02月04日
    浏览(49)
  • (超详细)C++图的深度优先遍历、广度优先遍历(数据结构)

            根据下图,编写代码实现图的深度优先遍历和广度优先遍历。          按照英文字母顺序,以邻接表为存储结构,实现图的深度优先和广度优先遍历。遍历的顺序从顶点a开始。 以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。   (1)从顶点a,

    2024年02月08日
    浏览(50)
  • 【数据结构】邻接矩阵和邻接图的遍历

    本篇文章开始学习数据结构的图的相关知识,涉及的基本概念还是很多的。 本文的行文思路: 学习图的基本概念 学习图的存储结构——本文主要介绍邻接矩阵和邻接表 对每种结构进行深度优先遍历和广度优先遍历 话不多说,狠活献上 等等,先别急,正式学习之前先认识几个

    2024年02月04日
    浏览(41)
  • 【数据结构与算法】图的遍历与拓扑排序

    再上一篇中我们讲了树的两种存储方式:【数据结构与算法】图——邻接表与邻接矩阵 这一篇我们可以用数组来模拟邻接表。 假设现在我们要进行n次操作,实现无向图。 首先需要一个 保存是哪个节点 的数组 e 然后就是类似指针数组的 表 h ,每个表都会连一串单链表 e,ne

    2024年02月04日
    浏览(34)
  • 《数据结构》实验报告六:图的表示与遍历

    1、掌握图的 邻接矩阵 和 邻接表 表示 2、掌握图的 深度优先 和 广度优先 搜索方法 3、理解 图的应用 方法 说明以下概念 1、深度优先搜索遍历:        一种图的遍历方式:从图中 任意一个 起始顶点 V 出发,接着访问它的任意一个 邻接顶点 W1 ;再从 W1 出发,访问与 W1

    2024年02月06日
    浏览(48)
  • Java高阶数据结构 & 图 & 图的表示与遍历

    高阶数据结构! 图是由顶点集合及顶点间的关系组成的一种数据结构: G = ( V , E ) G raph图, v ertex顶点, e dge边 其中: 顶点集合 V = {x|x属于某个数据对象集}是有穷非空集合; E = {(x,y)|x,y属于V}或者E = {|x,y属于V Path(x, y)} ,是顶点间关系的有穷集合,也叫做边的集合。 (x, y

    2024年02月04日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包