Graph 无向图中的桥

Graph 无向图中的桥,graph,Graph,桥只能存在于两个铰接点之间或铰接点与阶数为1的节点之间。 这只是一个观察,因为如果一个顶点是连接点,那么简单地从该节点断开连接只会给我们提供桥 请告诉我这是真是假。在无向图中,桥只能存在于两个连接点之间。这直接来自于定义: 桥是一条边,因此从图形中删除它会增加连接组件的数量 如果删除其任何端点,则也会增加连接组件的数量,这正是关节点的定义 我不知道你说的零件是什么意思,也不知道你说的关节点和没有0度的节点之间是什么意思。在无向图中,出度意味着什么 是Tarjan算法的精美幻灯片,包括其用于检

桥只能存在于两个铰接点之间或铰接点与阶数为1的节点之间。 这只是一个观察,因为如果一个顶点是连接点,那么简单地从该节点断开连接只会给我们提供桥


请告诉我这是真是假。

在无向图中,桥只能存在于两个连接点之间。这直接来自于定义:

  • 桥是一条边,因此从图形中删除它会增加连接组件的数量
  • 如果删除其任何端点,则也会增加连接组件的数量,这正是关节点的定义
我不知道你说的零件是什么意思,也不知道你说的关节点和没有0度的节点之间是什么意思。在无向图中,出度意味着什么

是Tarjan算法的精美幻灯片,包括其用于检测图形中的桥梁和连接点。

“关键问题是确定可达性关系如何影响 顶点v是铰接顶点。有三种情况: •根切割节点–如果DFS树的根有两个或多个子节点,则必须 是连接顶点。第二个子树的任何边都不能 可能连接到第一个子树的子树。 •桥接切割节点–如果从v最早到达的顶点是v,则删除 单条边(父[v],v)断开图形的连接。显然父[v]必须 是一个连接顶点,因为它从图上切下v。顶点v也是一个连接顶点 连接顶点,除非它是DFS树的叶子。对于任何叶子,都没有 剪下来的时候会掉下来。 •父切割节点–如果从v最早到达的顶点是v的父节点, 然后删除父级必须从树中断开v,除非父级是 根。“-Steve Skiena的算法设计手册

/*示例文件应包含以下边
/*A sample file should contain edges as follow
1,2
2,3
4,5
5,3
Output will give the set of bridge nodes
*/
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct graph
{
  int node;
  struct graph *next;
}graph;
void init(int group[],int index[],graph *g[]);
void create_graph(graph *g[],int node1,int node2,int group[],int index[],int max_nodes);
int max(int a,int b);
int min(int a,int b);
void display(graph *g[],int group[],int max_nodes);
int query(graph *g[],int group[],int max_nodes,int first,int second);
void delete_node(graph *g[],int node1,int node2,int group[],int index[],int max_nodes);
int team=0;
int main()
{
  char filename[50],ch;
  int nodes[MAX][2],temp=0,node1,node2,group[MAX],index[MAX],max_nodes=0,i;
  FILE *fp;
  graph *g[MAX],*p;
  init(group,index,g);
  printf("Enter the filename - ");
  scanf("%s",filename);
  fp=fopen(filename,"r");
  if(fp==NULL)
  {
    printf("File does not exist");
    exit(1);
  }
  while(1)
  {
    ch=fgetc(fp);
    if(isdigit(ch))
    temp=temp*10+(ch-48);
    else
    {
      if(ch!=','&&ch!='\n'&&ch!=EOF)
      exit(1);
      if(ch==',')
      node1=temp;
      else
      {
        node2=temp;
        if(node1>max_nodes)
        max_nodes=node1;
        if(node2>max_nodes)
        max_nodes=node2;
        if(node1!=node2&&node1>0&&node2>0)
        create_graph(g,node1,node2,group,index,max_nodes);
      }
      temp=0;
    }
    if(ch==EOF)
    {
      break;
    }
  }
  display(g,group,max_nodes);
  temp=0;
  fclose(fp);
  fp=fopen(filename,"r");
  printf("Set of bridges existing - \n\n");
  while(1)
  {
    ch=fgetc(fp);
    if(isdigit(ch))
    temp=temp*10+(ch-48);
    else
    {
      if(ch!=','&&ch!='\n'&&ch!=EOF)
      exit(1);
      if(ch==',')
      node1=temp;
      else
      {
        node2=temp;
        if(node1>max_nodes)
        max_nodes=node1;
        if(node2>max_nodes)
        max_nodes=node2;
        if(node1!=node2&&node1>0&&node2>0)
        delete_node(g,node1,node2,group,index,max_nodes);
      }
      temp=0;
    }
    if(ch==EOF)
    {
      break;
    }
  }
  return 0;
}
void init(int group[],int index[],graph *g[])
{
  int i;
  graph *p=NULL;
  for(i=0;i<MAX;i++)
  {
    group[i]=index[i]=0;
    g[i]=(graph *)malloc(sizeof(graph));
    g[i]->node=0;
    g[i]->next=NULL;
  }
}
void create_graph(graph *g[],int node1,int node2,int group[],int index[],int max_nodes)
{
  int temp_index,other_index,i,minimum;
  int stack[MAX],stack_index=0;
  graph *p;
  p=g[node1];
  if(p->next)
  {
    p=p->next;
    while(p)
    {
      if(p->node==node2)
      return;
      p=p->next;
    }
  }
  if(g[node1]->node<g[node2]->node)
  {
    temp_index=node1;
    other_index=node2;
  }
  else
  {
    temp_index=node2;
    other_index=node1;
  }
  p=g[temp_index];
  p->node=p->node+1;
  while(p->next!=NULL)
  p=p->next;
  p->next=(graph *)malloc(sizeof(graph));
  p=p->next;
  p->node=other_index;
  p->next=NULL;
  p=g[other_index];
  p->node=p->node+1;
  while(p->next)
  p=p->next;
  p->next=(graph *)malloc(sizeof(graph));
  p=p->next;
  p->node=temp_index;
  p->next=NULL;
  if(group[temp_index]==group[other_index]&&group[temp_index]==0)
  {
    {
      team++;
      group[temp_index]=group[other_index]=team;
    }
  }
  else
  {
    if(group[temp_index]==0)
    {
      group[temp_index]=group[other_index];
    }
    {
      minimum=min(group[temp_index],group[other_index]);
      group[temp_index]=max(group[temp_index],group[other_index]);
      for(i=1;i<=max_nodes;i++)
      {
        if(group[i]==minimum)
        group[i]=max(group[temp_index],group[other_index]);
      }
    }
  }
}
int max(int a,int b)
{
  if(a>b)
  return a;
  return b;
}
int min(int a,int b)
{
  if(a<b)
  return a;
  return b;
}
void display(graph *g[],int group[],int max_nodes)
{
  int i;
  graph *p;
  printf("Graph\n");
  printf("Id\tGrp\tNodes\n");
  for(i=1;i<=max_nodes;i++)
  {
    printf("%d\t%d\t%d",i,group[i],g[i]->node);
    p=g[i]->next;
    while(p)
    {
      printf(" %d",p->node);
      p=p->next;
    }
    printf("\n");
  }
  printf("\n\n");
}
int query(graph *g[],int group[],int max_nodes,int first,int second)
{
  if(group[first]==group[second])
  return 1;
  else
  return 0;
}
void delete_node(graph *g[],int node1,int node2,int group[],int index[],int max_nodes)
{
  graph *p=NULL;
  int i,temp,stack_index=0,stack[MAX];
  p=g[node1];
  while(p->next->node!=node2&&p->next)
  p=p->next;
  if(p->next)
  {
    p->next=p->next->next;
    g[node1]->node=g[node1]->node-1;
  }
  p=g[node2];
  while(p->next->node!=node1&&p->next)
  p=p->next;
  if(p->next)
  {
    p->next=p->next->next;
    g[node2]->node=g[node2]->node-1;
  }
  team++;
  group[node2]=team;
  stack_index=0;
  temp=node2;
  p=g[temp]->next;
  while(p)
  {
    stack[stack_index++]=p->node;
    p=p->next;
  }
  for(i=0;i<stack_index;i++)
  {
    if(group[stack[i]]!=team)
    {
      group[stack[i]]=team;
      p=g[stack[i]]->next;
      while(p)
      {
        stack[stack_index++]=p->node;
        p=p->next;
      }
    }
  }
  if(query(g,group,max_nodes,node1,node2)==0)
  printf("%d %d\n",node1,node2);
  create_graph(g,node1,node2,group,index,max_nodes);
}
1,2 2,3 4,5 5,3 输出将给出网桥节点集 */ #包括 #包括 #定义最大值100 类型定义结构图 { int节点; 结构图*下一步; }图形; void init(int-group[],int-index[],graph*g[]); void create_图(图*g[],int node1,int node2,int group[],int index[],int max_节点); int max(int a,int b); int min(int a,int b); 无效显示(图形*g[],整数组[],整数最大节点); int查询(图*g[],int组[],int max_节点,int第一,int第二); void delete_节点(图*g[],int node1,int node2,int group[],int index[],int max_节点); int团队=0; int main() { 字符文件名[50],ch; int节点[MAX][2],temp=0,节点1,节点2,组[MAX],索引[MAX],最大节点=0,i; 文件*fp; 图*g[MAX],*p; init(组,索引,g); printf(“输入文件名-”; scanf(“%s”,文件名); fp=fopen(文件名,“r”); 如果(fp==NULL) { printf(“文件不存在”); 出口(1); } 而(1) { ch=fgetc(fp); if(isdigit(ch)) 温度=温度*10+(ch-48); 其他的 { if(ch!=','&&ch!='\n'&&ch!=EOF) 出口(1); 如果(ch==',') 节点1=温度; 其他的 { 节点2=温度; if(节点1>最大节点数) 最大节点数=节点1; 如果(节点2>最大节点数) 最大节点数=节点2; if(node1!=node2&&node1>0&&node2>0) 创建_图(g、node1、node2、组、索引、最大_节点); } 温度=0; } 如果(ch==EOF) { 打破 } } 显示(g、组、最大节点); 温度=0; fclose(fp); fp=fopen(文件名,“r”); printf(“现有桥梁集-\n\n”); 而(1) { ch=fgetc(fp); if(isdigit(ch)) 温度=温度*10+(ch-48); 其他的 { if(ch!=','&&ch!='\n'&&ch!=EOF) 出口(1); 如果(ch==',') 节点1=温度; 其他的 { 节点2=温度; if(节点1>最大节点数) 最大节点数=节点1; 如果(节点2>最大节点数) 最大节点数=节点2; if(node1!=node2&&node1>0&&node2>0) 删除节点(g、节点1、节点2、组、索引、最大节点); } 温度=0; } 如果(ch==EOF) { 打破 } } 返回0; } void init(整数组[],整数索引[],图形*g[]) { int i; 图*p=NULL; 对于(i=0;inode=0; g[i]>next=NULL; } } void create_图(图*g[],int node1,int node2,int group[],int index[],int max_节点) { int temp_index,其他_index,i,最小值; int stack[MAX],stack_index=0; 图*p; p=g[node1]; 如果(p->next) { p=p->next; while(p) { 如果(p->node==node2) 返回; p=p->next; } } if(g[node1]->nodenode) { 温度指数=节点1; 其他_指数=节点2; } 其他的 { 温度指数=节点2; 其他_指数=节点1; } p=g[温度指数]; p->node=p->node+1; while(p->next!=NULL) p=p->next; p->next=(图*)malloc(图的大小); p=p->next; p->node=其他_索引; p->next=NULL; p=g[其他指数]; p->node=p->node+1; while(p->next) p=p->next; p->next=(图*)malloc(图的大小); p=p->next; p->node=temp\u索引; p->next=NULL; 如果(组[临时索引]==组[其他索引]&&组[临时索引]==0) { { 团队++; 组[临时索引]=组[其他索引]=团队; } } 其他的 { 如果(组[临时索引]==0) { 组[临时索引]=组[其他索引]; } { 最小值=最小值(组[临时指数]、组[其他指数]); 组[临时指数]=最大值(组[临时指数]、组[其他指数]); 对于(i=1;ib) 返回a; 返回b; } 最小整数(整数a,整数b) { if(anext; while(p) { printf(“%d”,p->node); p=p->next; } printf(“\n”); } printf(“\n\n”); } int查询(图*g[],int组[],int max_节点,int第一,int第二) { if(组[第一]==组[第二]) 返回1; 其他的 返回0; } void delete_节点(图*g[],int节点1,int节点2,int组[],int索引[],int max_节点) { 图*p=NULL; int i,temp,堆栈索引=0,堆栈[MAX]; p=g[node1]; while(p->next->node!=node2&&p->next) p=p->next; 如果(p->next) { p->next=p->next->next; g[node1]->node=g[node1]->node-1; } p=g[node2]; 而(p->next->node!=node1&&p->next) p=p->n