关节点

定义

在连通图 G 中,如果删除顶点 u 及从 u 出发的所有边后所得的子图不连通,我们就称顶点 u 为图 G 的关节点或连接点。 

原理

  要解决这道题,我们可以检查图在单独删除各顶点之后的连通性,但这个算法要对每个顶点执行一次DFS, 效率不高。

  不过,只要我们如下将DFS加以应用,就可以有效地找出图 G 中所有的关节点了。

  在一次DFS中求以下变量值。

  ?prenum[u]:以 G 的任意顶点作为起点进行DFS,将各顶点 u 的访问(首次发现)顺序记录在prenum[u]中。

  ?parent[u]:通过DFS生成一棵树(DFS Tree),将其中结点 u 的父节点记录在parent[u]中。这里将DFS Tree记作T。

  ?lowest[u]:对于各顶点 u,计算下列情况的最小值并记入lowest[u]

     ① prenum[u]

     ② 存在 G 的Back(u, v)时,顶点 v 的prenum[v](Back(u, v)表示图 G 内 ”从顶点 u 出发指向 T 内的顶点 v“ 且 ”不属于 T “的边)

     ③ T 内顶点 u 的所以子节点 x 的lowest[u]

  有了这些变量,我们便可以通过下述方法确定关节点。

  ① T 的根节点 r 拥有 2 个以上子节点时(充分必要条件),r 为关节点。

  ② 对于各顶点 u,设 u 的父节点parent[u] 为 p ,如果prenum[p] <= lowest[u] (充分必要条件),则 p 为关节点(p 为根节点时则套用 ①)。这表明顶点 u 及 u 在 T 中的子孙均不具备与 p 的祖先相连的边。

实现

如图,G 代表图 G,T 代表以顶点 0 为起点对 G 执行DFS后得到的DFS Tree。T 的Back edges 用虚线标出,各顶点 u 的左侧数字为prenum[u]:lowest[u]。prenum[u]为DFS中各顶点 u 的被访问顺序:按照 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7的顺序记录。

lowest[u]是DFS过程中各顶点 u 访问结束的顺序:按照 4 -> 7 -> 6 -> 5 -> 3 -> 2 -> 1 -> 0的顺序算出。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000;
vector<int> G[maxn];
bool vis[maxn];
int N,prenum[maxn],parent[maxn],lowest[maxn],timer=1;
void dfs(int current,int prev);
void art_points();
int main()
{
  int i,m,s,t;
  cin>>N>>m;
  for(i=0;i<m;i++)
  {
    cin>>s>>t;
    G[s].push_back(t);
    G[t].push_back(s);
  }
  art_points();
  system("pause");
  return 0;
}
void art_points()
{
  int i,np=0,p;
  set<int> ap;
  dfs(0,-1);
  for(i=1;i<N;i++)
  {
    p=parent[i];
    if(p==0) np++;
    else if(prenum[p]<=lowest[i]) ap.insert(p);
  }
  if(np>1) ap.insert(0);
  for(set<int>::iterator it=ap.begin();it!=ap.end();it++)
   cout<<*it<<endl;
}
void dfs(int current,int prev)
{
  int next,i;
  prenum[current]=lowest[current]=timer;
  timer++;
  vis[current]=1;
  for(i=0;i<G[current].size();i++)
  {
    next=G[current][i];
    if(!vis[next])
    {
      parent[next]=current;
      dfs(next,current);
      lowest[current]=min(lowest[current],lowest[next]);
    }
    else if(next!=prev)
      lowest[current]=min(lowest[current],prenum[next]);
  }
}

转载于:https://www.cnblogs.com/VividBinGo/p/11600998.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,可以使用OpenCV库来进行关节点捕捉。OpenCV是一个跨平台的计算机视觉和机器学习软件库,提供了图像处理和计算机视觉方面的通用算法。它支持多种编程语言的接口,包括Python。通过使用OpenCV的函数和方法,可以实现对图像中的关节点进行捕捉。 要进行关节点捕捉,可以使用Mediapipe库。Mediapipe是一个开源的跨平台框架,用于构建各种视觉和感知应用程序。它提供了一系列预训练的模型和算法,可以用于关节点检测、姿势估计等任务。 在使用Python和OpenCV进行关节点捕捉时,可以按照以下步骤进行操作: 1. 安装OpenCV和Mediapipe库。可以使用pip命令来安装这些库,例如: ``` pip install opencv-python pip install mediapipe ``` 2. 导入所需的库和模块: ```python import cv2 import mediapipe as mp ``` 3. 创建一个Mediapipe的关节点检测器: ```python mp_drawing = mp.solutions.drawing_utils mp_pose = mp.solutions.pose pose = mp_pose.Pose() ``` 4. 读取图像或视频,并进行关节点捕捉: ```python image = cv2.imread('image.jpg') # 读取图像 # 或者 cap = cv2.VideoCapture('video.mp4') # 读取视频 while cap.isOpened(): success, frame = cap.read() if not success: break # 将图像转换为RGB格式 image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 进行关节点捕捉 results = pose.process(image_rgb) # 在图像上绘制关节点 mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) cv2.imshow('MediaPipe Pose', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() ``` 这样,你就可以使用Python和OpenCV进行关节点捕捉了。通过调用Mediapipe的关节点检测器,可以获取到图像中的关节点位置,并在图像上绘制出来。 #### 引用[.reference_title] - *1* *3* [基于Opencv+Mediapipe实现手势追踪](https://blog.csdn.net/weixin_62343847/article/details/122664231)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [python抓取视频中的人物动作,并生成3D的bvh](https://blog.csdn.net/qwer492915298/article/details/112321642)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值