c++数据结构-图(详解附算法代码,一看就懂)

图(Graph)是一种复杂的非线性结构,它可以描述数据间的关系,被广泛使用。

图 G 由两个集合 V 和 E 组成,记为 。V是顶点的有穷非空集合,E是边的集合。通常,也将 G 的顶点集和边集表示为 V(G) 和 E(G)。其中,E(G)可以是空集,如果它是空集,那么 G 只有顶点。

图的定义和概念
有向图:边上有箭头,只能从箭头的引出的结点到被指向的结点,不能逆着箭头走。

无向图:边上无箭头,可以随便走。

结点的度:无向图中与结点相连的边的数量。

结点的入度:有向图中以结点为终点的边的数量。

结点的出度:有向图中以结点为起点的边的数量。

权值:可以理解为边的长度。

连通:如果结点 U 和 V 之间通过若干个边和结点能从 U 到达 V,则称 U 和 V 连通。

回路:起点和终点相同的路径。

完全图:一个 n 阶的完全无向图含有 n*(n-1)/2 条边,一个 n 阶的完全有向图含有 n*(n-1) 条边。

稠密图:一个边数接近完全图的图。

稀疏图:一个边数远少于完全图的图。

强连通分量:有向图中任意两点都连通的最大子图。特殊的,一个点也算一个强连通分量。

图的存储结构
二维数组邻接矩阵存储

定义 int G[101][101];

G[i][j] 的值,表示点 i 到点 j 的边的权值,定义如下,

G[i][j]{1或权值,0或无穷

深度优先和广度优先遍历
从图中某一顶点出发,系统的访问图中所有顶点,并且每个顶点只被访问一次,这种操作叫做图的遍历。为了不重复访问,我们使用一个数组 visit[] ,被访问过就变成 true,反之 false。这两种方法(广度和深度优先遍历)时间复杂度都是 O(n*n)。

深度优先遍历
深度优先遍历和深度优先搜索相似,它是先访问一个点,再访问与这个点相连的所有点,当这个点所有相连的点访问完,再退回下一个点。

广度优先遍历
它基本不用,和广度优先搜索相似,和深度优先遍历相似,这里不讲解。

一笔画问题
如果一个图存在一笔画,则一笔画的路径叫做欧拉路,如果起点和终点相同,则这个路径叫欧拉回路。

奇点是与一个点相连的边数是奇数的点。我们有如下两个定理:

(1)存在欧拉路的条件:图是连通的,且有且只有两个奇点。

(2)存在欧拉回路的条件:图是联通的,且有0个奇点。

#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int p[N],q[N];
int n,m;
int sum=0,flag=0;
int find(int x)
{
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) p[i]=i;
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        q[a]++;//由于是无向图需要把所有边加上
        q[b]++;
        a=find(a),b=find(b);
        if(a!=b) p[a]=b;
    }
    for(int i=1;i<=n;i++) 
        if(p[i]==i) sum++;
       if(sum==1)
       {
           for(int i=1;i<=n;i++)
           {
               if(q[i]%2!=0)
                   flag++;
           }
       }
     else {cout<<"N"<<endl;return 0;}
     if(flag==0 || flag==2) cout<<"Y"<<endl;//一笔画的规律(奇数点个数为0或者2)
     else cout<<"N"<<endl;
    return 0;
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Marching Squares算法是一种用于绘制等高线算法,它可以将二维数据转换为等高线算法原理: Marching Squares算法的基本原理是将二维数据划分为网格,然后对每个网格进行计算,判断每个网格是否需要绘制等高线。具体步骤如下: 1. 将二维数据划分为网格,每个网格包括四个顶点和四条边。 2. 对于每个网格,根据四个顶点的数值大小,将其分为16种情况。 3. 根据分割情况,确定每个网格需要绘制的等高线。 4. 对所有需要绘制等高线的点进行插值,得到等高线的精确位置。 5. 绘制等高线。 C++调用代码: 下面是C++代码的一个示例,用于演示如何使用Marching Squares算法绘制等高线。 ``` #include <iostream> #include <vector> using namespace std; // 数据结构定义 struct Point { double x, y; }; // 定义等高线数据 vector<vector<double>> data = { {1.1, 1.2, 1.3, 1.4, 1.5}, {1.2, 1.3, 1.4, 1.5, 1.6}, {1.3, 1.4, 1.5, 1.6, 1.7}, {1.4, 1.5, 1.6, 1.7, 1.8}, {1.5, 1.6, 1.7, 1.8, 1.9} }; // 定义等高线值 vector<double> contourValues = {1.4, 1.6, 1.8}; // 定义网格大小 int gridSize = 5; // 定义函数:获取网格中的四个值 vector<double> getGridValues(int i, int j) { vector<double> values; values.push_back(data[i][j]); values.push_back(data[i+1][j]); values.push_back(data[i+1][j+1]); values.push_back(data[i][j+1]); return values; } // 定义函数:判断是否需要绘制等高线 bool needContour(double value, double contourValue) { return value >= contourValue; } // 定义函数:计算等高线的精确位置 Point interpolate(Point p1, Point p2, double v1, double v2, double contourValue) { double mu = (contourValue - v1) / (v2 - v1); Point p; p.x = p1.x + mu * (p2.x - p1.x); p.y = p1.y + mu * (p2.y - p1.y); return p; } // 定义函数:绘制等高线 void drawContour(double contourValue) { // 定义等高线点集合 vector<Point> contourPoints; // 遍历每个网格 for (int i = 0; i < gridSize - 1; i++) { for (int j = 0; j < gridSize - 1; j++) { // 获取网格中的四个值 vector<double> values = getGridValues(i, j); // 判断是否需要绘制等高线 vector<bool> isNeedContour; for (double value : values) { isNeedContour.push_back(needContour(value, contourValue)); } // 根据分割情况,确定等高线点 int index = 0; if (isNeedContour[0]) index |= 1; if (isNeedContour[1]) index |= 2; if (isNeedContour[2]) index |= 4; if (isNeedContour[3]) index |= 8; // 定义等高线点 vector<Point> points; switch (index) { case 1: case 14: points.push_back(interpolate({i, j}, {i, j+1}, values[0], values[3], contourValue)); break; case 2: case 13: points.push_back(interpolate({i, j+1}, {i+1, j+1}, values[1], values[2], contourValue)); break; case 3: case 12: points.push_back(interpolate({i, j}, {i+1, j}, values[0], values[1], contourValue)); break; case 4: case 11: points.push_back(interpolate({i+1, j}, {i+1, j+1}, values[2], values[1], contourValue)); break; case 5: points.push_back(interpolate({i, j}, {i, j+1}, values[0], values[3], contourValue)); points.push_back(interpolate({i+1, j}, {i+1, j+1}, values[2], values[1], contourValue)); break; case 6: case 9: points.push_back(interpolate({i, j+1}, {i+1, j+1}, values[1], values[2], contourValue)); points.push_back(interpolate({i, j}, {i+1, j}, values[0], values[1], contourValue)); break; case 7: case 8: points.push_back(interpolate({i, j}, {i+1, j}, values[0], values[1], contourValue)); points.push_back(interpolate({i+1, j}, {i+1, j+1}, values[2], values[1], contourValue)); break; case 10: points.push_back(interpolate({i, j+1}, {i+1, j+1}, values[1], values[2], contourValue)); points.push_back(interpolate({i, j}, {i, j+1}, values[0], values[3], contourValue)); break; } // 添加等高线点到等高线点集合中 for (Point p : points) { contourPoints.push_back(p); } } } // 绘制等高线 cout << "绘制等高线:" << contourValue << endl; for (Point p : contourPoints) { cout << "(" << p.x << ", " << p.y << ")" << endl; } } int main() { // 绘制等高线 for (double contourValue : contourValues) { drawContour(contourValue); } return 0; } ``` 以上是一个简单的C++调用代码示例,用于演示如何使用Marching Squares算法绘制等高线

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值