走訪次數還要另外紀錄
所以用DFS應該也無不可吧?
不知道有沒有更好的方法?
第一次莫名其妙的RE。
也不知道是哪裡有問題……
只好防呆一下。
(1)假設input給的兩點為同一點 -> edge to self node。
這時候不做update(),只做addg()。
(2)假設給的node跟ttl,其中node不為graph上的任一點,當然未走訪任一點。
所以不做走訪,直接回傳node數。
防呆之後,再上傳一次就莫名其妙AC了。
可能(1)跟(2)都要防呆一下就ok。
第一次用union,不知效果如何。
其實都是int,但是意義不太一樣。
一個是pointer of array的node,一個是array連出去的linked list node。
在array的field表示該數字,
linked list上的field表示該數字所在的位置。
原本想在linked list上也存該數字,
但是數字又要轉成位置,
所以就直接存位置,省去一次轉換。
/* ACM 336 A Node Too Far * mythnc * 2012/01/13 13:10:30 * run time: 0.052 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXNODE 30 /* save num in array node, but save pos in linked node */ typedef union name { int num, pos; } u; typedef struct node { u field; /* times: the ttl times */ int times; struct node *next; } Node; typedef enum {FALSE = 0, TRUE} bool; void input(int); int search(int); int addg(int); void update(int, int); int bfs(int, int); void addq(int); int deleteq(void); void freeg(void); Node graph[MAXNODE]; int numnode, front, end; int queue[MAXNODE]; bool visited[MAXNODE]; int main(void) { int edge, v, ttl, set, sum; set = 0; while (scanf("%d", &edge) && edge != 0) { input(edge); while (scanf("%d %d", &v, &ttl) && !(v == 0 && ttl == 0)) { sum = bfs(search(v), ttl); printf("Case %d: %d nodes not reachable from node %d with TTL = %d.\n", ++set, sum, v, ttl); } freeg(); } return 0; } /* input: receive edge and initialize graph */ void input(int n) { int i, v1, v2, pos1, pos2; for (i = numnode = 0; i < n; i++) { scanf("%d %d", &v1, &v2); pos1 = search(v1); if (pos1 == -1) pos1 = addg(v1); pos2 = search(v2); if (pos2 == -1) pos2 = addg(v2); if (pos1 != pos2) { update(pos1, pos2); update(pos2, pos1); } } } /* search: find v in graph. * if find return its position * else return -1 */ int search(int v) { int i; for (i = 0; i < numnode; i++) if (graph[i].field.num == v) return i; return -1; } /* addg: add v in graph and * return the postion of v */ int addg(int v) { graph[numnode].field.num = v; graph[numnode].next = NULL; return numnode++; } /* update: update the edges of pos1 and pos2 */ void update(int pos1, int pos2) { Node *pt, *tmp; tmp = (Node *)malloc(sizeof(Node)); tmp->field.pos = pos2; tmp->next = NULL; pt = graph[pos1].next; if (pt == NULL) { graph[pos1].next = tmp; return; } /* find last link node */ while (pt->next != NULL) pt = pt->next; pt->next = tmp; } /* bfs: do bfs. the times of bfs has to equal to ttl * return unvisited node number */ int bfs(int pos, int ttl) { int times, sum; Node *pt; sum = numnode; /* no such node */ if (pos == -1) return sum; /* init visited array, queue tag and graph[pos] times */ memset(visited, FALSE, MAXNODE * sizeof(int)); front = end = graph[pos].times = 0; visited[pos] = TRUE; sum--; if (graph[pos].times == ttl) return sum; addq(pos); while (front != end) { pos = deleteq(); for (times = graph[pos].times + 1, pt = graph[pos].next; pt; pt = pt->next) { pos = pt->field.pos; if (!visited[pos]) { visited[pos] = TRUE; sum--; graph[pos].times = times; if (times < ttl) addq(pos); } } } return sum; } /* addq: add the graph[pos] and its adjacency node * to queue */ void addq(int pos) { queue[end++] = pos; end %= MAXNODE; } /* deleteq: delete the 1st element in queue. * and return the element */ int deleteq(void) { int pos; pos = queue[front++]; front %= MAXNODE; return pos; } /* freeg: free graph node */ void freeg(void) { Node *pt, *tmp; int i; for (i = 0; i < numnode; i++) { pt = graph[i].next; while (pt != NULL) { tmp = pt; pt = pt->next; free(tmp); } } }
沒有留言:
張貼留言