PAT 1076. Forwards on Weibo (BFS + 剪枝)

来源:互联网 发布:linux mount 远程目录 编辑:程序博客网 时间:2024/05/18 11:26

一开始想floyd, 但n^3 = 10^9, 要10秒了可能;

土一点的dijkstra超时, 因为dijkstra中寻找当前未访问过的距离最小值时,是对所有点进行遍历;以及对每个这样的点,是遍历map[1010][1010]数组。这样导致每遍dijkstra就是O(2*n*n)的复杂度。如果m >= n, 仍可能出现n^3的情况;

然后及用priority_queue来维护当前未访问过的距离最小值,用邻接表来维护每个点的相邻结点。

事实上,这就退化成BFS了.... 所以BFS+剪枝就能搞定的。(代码从135行变成了75行)


注意到,这里的边是有向边 —— "n l"后的第 i 行输入:

代表用户 i 关注了 m 个用户, 进而是该m个的用户的微博可以被用户 i 转发,从而有向边应该从那些 m 个用户指向 i.


代码。耗时2s. 有人耗时200+ms就完成了,知道怎么做的教我一下呗。

#include <iostream>#include <queue>#include <list>#include <cstring>using namespace std;struct Node{int m_id;int m_level;Node() {}Node(int id, int level): m_id(id), m_level(level) {}};int n, l, k, id;bool in_queue[1010];list<int> edge[1010];queue<Node> q;int bfs(Node now){//cout << "bfs" << endl;int cnt = -1;while (q.empty() == false){q.pop();}q.push(now);in_queue[now.m_id] = true;while (q.empty() == false){Node node = q.front();//in_queue[node.m_id] = true;q.pop();if (node.m_level > l){break;}//cout << node.m_id << endl;++ cnt;for (auto it = edge[node.m_id].begin(); it != edge[node.m_id].end(); ++ it){if (in_queue[*it] == false){q.push( Node(*it, node.m_level+1) );in_queue[*it] = true;}}}return cnt;}int main(){scanf("%d%d", &n, &l);for (int i = 1; i <= n; ++ i){scanf("%d", &k);for (int j = 0; j < k; ++ j){scanf("%d", &id);edge[id].push_back(i);}}scanf("%d", &k);for (int i = 0; i < k; ++ i){memset(in_queue, 0, sizeof(in_queue));scanf("%d", &id);printf("%d\n", bfs(Node(id, 0)));}return 0;}


耗时220ms.. 不懂怎么做到的

0 0