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) ? '
' : ' ');
			}
		}
	}
	return 0;
}


原文地址:https://www.cnblogs.com/wiklvrain/p/8179356.html