Sparse Graph(2016大连网赛)(hdu5876)(BFS+数据结构)
2016-09-11 17:56
225 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5876
题意:给一个起点和一个原图,问从起点到原图补图(原图中连着的点在补图中不连,不连的点在补图中连)的每个点的最短距离。每条边的长度都是1.
题解:由于每条边的长度都是1,所以可以用BFS,从起点开始一层一层BFS。可是由于要在补图上跑,所以要反向思考一下,把所有与当前搜索到节点连着的点都从这个点所能到达集合里面去掉。而且这道题的数据量有点大,时间复杂度有点坑,如果每一次都遍历所有的点的话,会惨烈的超时。
所以用了两个集合。
一个集合s1初始时是所有还没有被搜索到的点,即将要存储现在所有没有到达但这一次BFS可以到达的点。一个集合s2存储现在还没有到达的,且这一次BFS不能到达的点。
如果u在原图中可以到达点v,那么在补图中就不能到达点v,所以就要把v加入s2,并在s1中除去。
s1、s2更新的时候就已经把原来到达过的点去掉了,所以时间复杂度一下子就下来了,也就是一个元素,如果已经被搜索过了,那么将不会参加后续操作,时间复杂度一下子就下来了。(好神奇)
思考:
1、用数据结构优化代码复杂度
2、做题太少,知道的姿势太少
代码:
题意:给一个起点和一个原图,问从起点到原图补图(原图中连着的点在补图中不连,不连的点在补图中连)的每个点的最短距离。每条边的长度都是1.
题解:由于每条边的长度都是1,所以可以用BFS,从起点开始一层一层BFS。可是由于要在补图上跑,所以要反向思考一下,把所有与当前搜索到节点连着的点都从这个点所能到达集合里面去掉。而且这道题的数据量有点大,时间复杂度有点坑,如果每一次都遍历所有的点的话,会惨烈的超时。
所以用了两个集合。
一个集合s1初始时是所有还没有被搜索到的点,即将要存储现在所有没有到达但这一次BFS可以到达的点。一个集合s2存储现在还没有到达的,且这一次BFS不能到达的点。
如果u在原图中可以到达点v,那么在补图中就不能到达点v,所以就要把v加入s2,并在s1中除去。
s1、s2更新的时候就已经把原来到达过的点去掉了,所以时间复杂度一下子就下来了,也就是一个元素,如果已经被搜索过了,那么将不会参加后续操作,时间复杂度一下子就下来了。(好神奇)
思考:
1、用数据结构优化代码复杂度
2、做题太少,知道的姿势太少
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <queue> #include <iterator> using namespace std; const int maxn = 200010 * 5; const int maxm = 20010; int cnt; int n, m, s; int head[maxn]; int d[maxn]; struct Edge{ int v, next, c; }edge[maxn]; void addedge(int u, int v, int c) { edge[cnt].v = v; edge[cnt].c = c; edge[cnt].next = head[u]; head[u] = cnt++; } void init() { cnt = 0; memset (head, -1, sizeof(head)); memset (d, -1, sizeof(d)); } void BFS() { set<int> s1; set<int> s2; for (int i = 1; i <= n; i++) { s1.insert(i); } d[s] = 0; s1.erase(s); queue<int> q; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i != -1; i = edge[i].next) { int v= edge[i].v; if (!s1.count(v)) continue; s1.erase(v); s2.insert(v); } for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) { q.push(*it); d[*it] = d[u] + 1; } s1.swap(s2); s2.clear(); } } int main() { int t; scanf ("%d", &t); while (t--) { scanf ("%d%d", &n, &m); init (); for (int i = 0; i < m; i++) { int u, v; scanf ("%d%d", &u, &v); addedge (u, v, 1); addedge (v, u, 1); } scanf ("%d", &s); BFS (); if (s == 1) { printf ("%d", d[2]); for (int i = 3; i <= n; i++) { printf (" %d", d[i]); } } else { printf ("%d", d[1]); for (int i = 2; i <= n; i++) { if (i == s) continue; printf (" %d", d[i]); } } printf ("\n"); } return 0; }
相关文章推荐
- 2016 ICPC 大连网络赛 HDU 5876 Sparse Graph
- 【2016-大连赛区网络赛-I】补图最短路(Sparse Graph,hdu 5876)
- 2016大连网络赛Sparse Graph
- hdu 5876 - Sparse Graph(2016大连网络赛) bfs
- HDU 5876 Sparse Graph (补图BFS) 2016 ACM/ICPC Asia Regional Dalian Online
- hdu5876 Sparse Graph(最短路)
- HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)
- HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)
- HDU 5876 大连网络赛 Sparse Graph
- 【icpc网络赛大连赛区】Sparse Graph
- hdu 5876 Sparse Graph(补图最短路) 2016 ACM/ICPC Asia Regional Dalian Online 1009
- hdu5876 Sparse Graph bfs + set
- HDU 5876 大连网络赛 Sparse Graph
- HDU 5876 Sparse Graph(bfs求解补图中的单源最短路)——2016 ACM/ICPC Asia Regional Dalian Online
- hdu5876 Sparse Graph -补图的最短路-bfs
- HDU5876 Sparse Graph 补图的最短路
- 补图上的BFS大连网络赛Sparse Graph
- hdu5876 Sparse Graph(补图+最短路)
- HDU 5867 Sparse Graph (2016年大连网络赛 I bfs+补图)
- HDU 5876 Sparse Graph(2016 ACM/ICPC Asia Regional Dalian Online)