/* 逼着自己去写邻接表,xwc给我讲过大致如何构造,听其实还是简单的。可是写起来稍微有点困难的 光是建表就很纠结的,指针数组 和 数组 总是不能区别开来,最初很痛苦写好的,编译没有通过, 把这两个东西混起来,对于指针就是有一种莫名的不知道。很早xwc就鼓励我去写了,但是一直害怕麻烦就不敢尝试, 这是一个不好的毛病,为了不能让cdd 的苦心白费,我决定要学会邻接表 其实这道题目我很早就写了,当时MLE,就不知道怎么改,今天一开始用邻接写的也是同样的毛病 真不知怎么去改,xwc说肯定哪里有小错误,于是很兴奋地想把这纸老虎找出来,于是想到了距离为1的最短路的BFS 每次更新就是最短路,可以直接hash,不用弹出一个一个hash的,这应该是MLE的关键所在,修改了下,终于AC 对于树的BFS总是有点困惑的,当经过今天,我想大概明白了点什么,我只要在认真地学,肯定能学到东西的! */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int N = 10000; const int INF = 0x7f7f7f7f; struct node { int mu; struct node *next; }; node *map[N], ved[N];//这里怎么去用,开始的时候还是不知如何,数组是要用 ved[9].mu 的,不是用ved[9]->mu,zhc帮我改的 bool hash[N]; bool flag[N]; int dis[N]; int Dis[N]; void show() { for(int i = 0; i < N; i++) { map[i] = & ved[i]; } } void ctreat(int x, int y, int val) {//建立邻接表 node *p; p = new node; p->mu = y; p->next = NULL; map[x] ->next = p; map[x] = p; } struct Node { int dis; int num; }; void BFS(int s) { queue<Node> Q; Node P, M; memset(dis, 0x7f, sizeof(dis)); memset(hash, false, sizeof(hash)); map[s] = &ved[s]; for( node *p = map[s]->next; p != NULL; p = p ->next) { P.num = p->mu; P.dis = 1; dis[p->mu] = 1; hash[p->mu] = true; Q.push(P); } hash[s] = true; while(!Q.empty()) { M = Q.front(); Q.pop(); //hash[M.num] = true;//只这里hash的会MLE,看来是priority_queue 写逛了 dis[M.num] = M.dis; if(dis[M.num] > Dis[M.num]) Dis[M.num] = dis[M.num]; map[M.num] = & ved[M.num]; for(node *p = map[M.num]->next; p != NULL; p = p->next) { if(!hash[p->mu]) { P.num = p->mu; P.dis = M.dis + 1; dis[p->mu] = P.dis; hash[p->mu] = true; Q.push(P); } } } //free(p); } int main() { int t; scanf("%d", &t); while(t--) { int nz, nr; int v, r, y; int st = INF, et = -INF; memset(flag, false, sizeof(flag)); scanf("%d %d", &nz, &nr); show(); for(int i = 0; i < nz; i++) { scanf("%d %d", &v, &r); flag[v] = true; if(v < st) { st = v; } if(v > et) { et = v; } for(int j = 0; j < r; j++) { scanf("%d", &y); flag[y] = true; if(y < st) { st = y; } if(y > et) { et = y; } ctreat(v, y, 1); } } memset(Dis, 0, sizeof(Dis)); while(nr--) { scanf("%d", &r); for(int i = 0; i < r; i++) { scanf("%d", &y); BFS(y); } } int df = INF; int bb; for(int i = st; i <= et; i++) { if(Dis[i] < df && flag[i]) { df = Dis[i]; bb = i; } } printf("%d %d/n", df + 1, bb); } return 0; } /* AC之后顺便把以前的写的也改,以前用的是类似于邻接表的静态的邻接表 */ #include <iostream>//2223317 2010-07-12 18:02:22 Accepted 2913 C++ 270 752 悔惜晟 #include <queue> #include <cstdio> using namespace std; const int N = 10000; const int INF = 0x7f7f7f7f; int cost[N][12]; bool hash[N]; bool flag[N]; int dis[N]; int Dis[N]; struct node { int dis; int x; }; void BFS(int st,int en, int s) { queue<node>Q; node P, M; memset(dis, 0x7f, sizeof(dis)); memset(hash, false, sizeof(hash)); for(int i = 1; i <= 10; i++) { if(cost[s][i] != 0) { dis[cost[s][i]] = 1; hash[cost[s][i]] = true; P.dis = 1; P.x= cost[s][i]; Q.push(P); } } hash[s] = true; while(!Q.empty()) { P = Q.front(); Q.pop(); if(dis[P.x] > Dis[P.x]) Dis[P.x] = dis[P.x]; for(int i = 1; i <= 10; i++) { if(!hash[cost[P.x][i]] && cost[P.x][i] != 0) { dis[cost[P.x][i]] = P.dis + 1; hash[cost[P.x][i]] = true; M.dis = P.dis + 1; M.x = cost[P.x][i]; Q.push(M); } } } } int main() { int t; scanf("%d", &t); while(t--) { int z, r; memset(cost, 0, sizeof(cost)); memset(Dis, 0, sizeof(Dis)); memset(flag, false, sizeof(flag)); scanf("%d %d", &z, &r); int a, b, c; int st, en; st = INF; en = -INF; while(z--) { scanf("%d %d", &a, &b); flag[a] = true; if(a > en) en = a; if(a < st) st = a; cost[a][0] = a; for(int i = 1; i <= b; i++) { scanf("%d", &c); flag[c] = true; if(c > en) en = c; if(c < st) st = c; cost[a][i] = c; } } int bb; while(r--) { scanf("%d", &a); while (a--) { scanf("%d", &bb); BFS(st, en, bb); } } a = INF; for(int i = st; i <= en; i++) { if(Dis[i] < a && flag[i]) { a = Dis[i]; b = i; } } printf("%d %d/n", a + 1, b); } }