Quiet
  • HOME
  • ARCHIVE
  • CATEGORIES
  • TAGS
  • LINKS
  • ABOUT

ChenSir

  • HOME
  • ARCHIVE
  • CATEGORIES
  • TAGS
  • LINKS
  • ABOUT
Quiet主题
  • UESTC

卓中卓一轮第三题

ChenSir
UESTC

2024-06-08 00:00:03

  • 图中的支配关系

    • 定义一个带权有向图的数据结构如下:

      
      
      typedef struct GraphStruct{
          int   vertex_num;
          int   edge_num;
          int **edges;
      }GraphStruct;
      typedef struct GraphStruct *Graph;
      typedef unsigned int Vertex;
      
      typedef struct {
          Vertex v;
        Vertex w;
          int    weight;
      } Edge;

    其中 edges 指向图的邻接矩阵,矩阵元素为对应边上的权重(权重为自然数)。
    定义图中0结点为入口结点;
    定义dom关系为:如果从图的入口结点(即0结点)到结点 n 的每条路径都经过结点 d ,则称结点 d 支配(dominate) n ,记为 d dom n。
    根据该定义,每个结点支配它自己,且入口结点(即0结点)支配包括它自己在内的所有结点。

    请使用上述数据结构,从标准输入读入一个图(该图为联通图),请找出除入口结点外所有结点间的支配关系,并按下面示例样式输出:

    输入数据示例如下:

    
      
    5,6
    0,1,95
    0,2,41
    1,3,99
    1,4,67
    2,4,95
    3,4,99

    其中第1行分别为图中结点的个数 5、图中边的个数 6;之后的6行分别是各边的信息,以第2行为例,其表示结点0到1之间有权重为95的有向边,方向为0至1。根据支配关系的定义,该图的支配关系有:

    
      
    0 dom 0
    0 dom 1
    0 dom 2
    0 dom 3
    0 dom 4
    1 dom 1
    1 dom 3
    2 dom 2
    3 dom 3
    4 dom 4

    因0结点支配所有结点,所以不输出该信息;将其它支配关系按结点编号从小到大的顺序输出如下:

     
    
    (1#1)(1#3)(2#2)(3#3)(4#4)

    其中每一对括号表示一个支配关系,# 表示 dom

​ 以下是本人的题解

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct GraphStruct {
    int vertex_num;
    int edge_num;
    int **edges;
} GraphStruct;

typedef struct GraphStruct *Graph;
typedef unsigned int Vertex;

Graph create_graph(int vertex_num, int edge_num) {
    Graph g = (Graph)malloc(sizeof(GraphStruct));
    g->vertex_num = vertex_num;
    g->edge_num = edge_num;
    g->edges = (int **)malloc(vertex_num * sizeof(int *));
    for (int i = 0; i < vertex_num; i++) {
        g->edges[i] = (int *)calloc(vertex_num, sizeof(int));
    }
    return g;
}

void dfspro(Graph g, Vertex v, bool visitedpro[], int ignore) {
    visitedpro[v] = true;
    for (int w = 0; w < g->vertex_num; w++) {
        if (w != ignore && g->edges[v][w] != 0 && !visitedpro[w]) {
            dfspro(g, w, visitedpro, ignore);
        }
    }
}

void dfs(Graph g, Vertex v, bool visited[]) {
    visited[v] = true;
    for (int i = 0; i < g->vertex_num; i++) {
        if (g->edges[v][i] != 0 && !visited[i]) {
            dfs(g, i, visited);
        }
    }
}


void compute_dominators(Graph g) {
    printf("(");
    bool first = true;

    for (int d = 1; d < g->vertex_num; d++) {
        bool *visitedpro = (bool *)calloc(g->vertex_num, sizeof(bool));
        dfspro(g, 0, visitedpro, d);
        bool *visited = (bool *)calloc(g->vertex_num, sizeof(bool));
        dfs(g, 0, visited);
        for (int n = 0; n < g->vertex_num; n++) {
            if (visited[n] ^ visitedpro[n]) {
                if (!first) {
                    printf(")(");
                }
                printf("%d#%d", d, n);
                first = false;
            }
        }
    }

    printf(")\n");
}

int main() {
    int vertex_num, edge_num;
    scanf("%d,%d", &vertex_num, &edge_num);
    if (vertex_num <= 0 || edge_num <= 0) return 0;
    
    Graph g = create_graph(vertex_num, edge_num);

    for (int i = 0; i < edge_num; i++) {
        Vertex v, w;
        int weight;
        scanf("%u,%u,%d", &v, &w, &weight);
        g->edges[v][w] = weight;
    }

    compute_dominators(g);

    return 0;
}
上一篇

卓中卓二轮综合题

下一篇

卓中卓一轮第二题

©2025 By ChenSir. 主题:Quiet
Quiet主题