diff options
Diffstat (limited to 'dom.c')
-rw-r--r-- | dom.c | 155 |
1 files changed, 0 insertions, 155 deletions
@@ -1,155 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#define MAXN 1000 -#define MAX_HASH 1021 -typedef struct Edge Edge; -typedef struct Set Set; -typedef Set *Set_t; -typedef struct SetNode { - int val; - struct SetNode *next; -} SetNode; -struct Set { - SetNode *head[MAX_HASH]; -}; - -Set_t set_create() { - Set_t set = (Set_t)malloc(sizeof(Set)); - memset(set->head, 0, sizeof set->head); - return set; -} - -int set_belongs(Set_t set, int val) { - SetNode *p; - for (p = set->head[val % MAX_HASH]; p; p = p->next) - if (p->val == val) return 1; - return 0; -} - -void set_push(Set_t set, int val) { - SetNode *p = (SetNode*)malloc(sizeof(SetNode)); - int hv = val % MAX_HASH; - p->next = set->head[hv]; - p->val = val; - set->head[hv] = p; -} - -struct Edge { - int to; - Edge *next; -} *head[MAXN], *rhead[MAXN]; - -typedef struct DFNode DFNode; -struct DFNode { - int id; - DFNode *next; -}; - -void add_edge(int a, int b, Edge **head) { - Edge *p = (Edge*)malloc(sizeof(Edge)); - p->to = b; - p->next = head[a]; - head[a] = p; -} -int dom[MAXN], ord[MAXN], vis[MAXN], par[MAXN]; -int n, n0, m; -DFNode *df[MAXN]; -Set_t dfset[MAXN]; - -void dfs(int u, int v) { - static int ocnt = 0; - Edge *e; - if (vis[u] != -1) return; - par[u] = v; - vis[u] = 0; - for (e = head[u]; e; e = e->next) - dfs(e->to, u); - vis[u] = ocnt; - ord[ocnt++] = u; -} - -int intersect(int b1, int b2) { - while (b1 != b2) - if (b1 < b2) b1 = dom[b1]; - else b2 = dom[b2]; - return b1; -} - -int main() { - int i; - int ch = 1; - scanf("%d %d %d", &n, &m, &n0); - for (i = 0; i < m; i++) - { - int a, b; - scanf("%d %d", &a, &b); - add_edge(a, b, head); - add_edge(b, a, rhead); - } - for (i = 0; i < n; i++) - vis[i] = dom[i] = -1; - dfs(n0, -1); - for (i = 0; i < n; i++) - printf("%d ", ord[i]); puts(""); - dom[vis[n0]] = vis[n0]; - while (ch) - { - int i; - ch = 0; - for (i = n - 2; i >= 0; i--) - { - int id = ord[i]; - Edge *e = rhead[id]; - int new_idom = vis[par[id]]; - for (; e; e = e->next) - { - int p = e->to; - if (vis[p] == new_idom) continue; - if (dom[vis[p]] != -1) - new_idom = intersect(vis[p], new_idom); - } - if (dom[i] != new_idom) - { - ch = 1; - dom[i] = new_idom; - } - } - for (i = 0; i < n; i++) - printf("%d ", ord[dom[vis[i]]]); puts(""); - } - for (i = 0; i < n; i++) - { - dfset[i] = set_create(); - df[i] = NULL; - } - for (i = 0; i < n; i++) - if (rhead[i] && rhead[i]->next) - { - Edge *p = rhead[i]; - for (; p; p = p->next) - { - int runner = p->to; - while (vis[runner] != dom[vis[i]]) - { - if (!set_belongs(dfset[runner], i)) - { - DFNode *np = (DFNode*)malloc(sizeof(DFNode)); - np->id = i; - np->next = df[runner]; - set_push(dfset[runner], i); - df[runner] = np; - } - runner = ord[dom[vis[runner]]]; - } - } - } - for (i = 0; i < n; i++) - { - DFNode *p = df[i]; - printf("%d: ", i); - for (; p; p = p->next) - printf("%d ", p->id); puts(""); - } - return 0; -} |