HDU-5876 Sparse Graph
题目大意:
给你一个完全图让你删除给出的这些边形成新的图,问你在新的图上的s点到其它所有点的距离。
解题思路:
BFS乱搞...
补图的BFS的问题虽然很经典= =不过确实还是第一次做。很方。
用一个map来保存邻接的信息。因为最多20000,很坑的是比赛时候题面给的是5000
然后先从s来遍历所有点,如果邻接信息里面含有s到i的边,那么将i插入到set里面,并将dis[i]置为-1,如果不含有s到i的边,就将i插入队列,并将dis[i]置为1
然后依次访问队列里面的元素x,遍历set,如果set中的点y不具有一条x到y的边,那么就将这个点标记,取出set,然后更新dis[y]
当set为空的时候直接return。
其实set可以用链表代替不过用set可以偷懒...
大概思路就是这样。然后就可以解决这题了。
代码:
#include <set> #include <map> #include <queue> #include <cstdio> #include <cstring> using namespace std; const int maxm = 40005; const int maxn = 200005; set<int> ss; map<int, map<int, int> > mp; int dis[maxn]; void bfs(int s, int n) { queue<int> q; ss.clear(); while (!q.empty()) q.pop(); for (int i = 1; i <= n; ++i) { if (i == s) continue; if (mp[s][i]) { dis[i] = -1; ss.insert(i); } else { dis[i] = 1; q.push(i); } } int cnt = ss.size(); while (!q.empty()) { int x = q.front(); q.pop(); for (set<int>::iterator it = ss.begin(); it != ss.end(); ++it) { int y = *it; if (dis[y] != -1 || mp[x][y]) continue; dis[y] = dis[x] + 1; q.push(y); --cnt; } if (!cnt) return; } } int main() { int n, m, s, u, v, t; while (~scanf("%d", &t)) { while (t--) { mp.clear(); scanf("%d%d", &n, &m); while (m--) { scanf("%d%d", &u, &v); mp[u][v] = mp[v][u] = 1; } scanf("%d", &s); bfs(s, n); int cnt = 0; for (int i = 1; i <= n; ++i) { if (i == s) continue; ++cnt; printf("%d%c", dis[i], (cnt == n - 1) ? '\n' : ' '); } } } return 0; }