题意:在一张完全图上去掉m条边,问从一个点到其他点的最短路
解题思路:求一张补图的最短路,用set来维护还没走到的点
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <bitset> #include <functional> using namespace std; #define LL long long const int INF = 0x3f3f3f3f; int n, m, ss; int s[200009], nt[400009], e[400009], dis[200009]; void bfs(int ss) { set<int>st, ts; for (int i = 1; i <= n; i++) { dis[i] = 0; if (i != ss) st.insert(i); } set<int>::iterator it; dis[ss] = 0; queue<int>q; q.push(ss); while (!q.empty()) { int pre = q.front(); q.pop(); for (int i = s[pre]; ~i; i = nt[i]) { int ee = e[i]; if (!st.count(ee)) continue; st.erase(ee), ts.insert(ee); } for (it = st.begin(); it != st.end(); it++) { dis[*it] = dis[pre] + 1; q.push(*it); } st.swap(ts); ts.clear(); } } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); int cnt = 1, u, v; memset(s, -1, sizeof s); for (int i = 1; i <= m; i++) { scanf("%d%d", &u, &v); if (u == v) continue; nt[cnt] = s[u], s[u] = cnt, e[cnt++] = v; nt[cnt] = s[v], s[v] = cnt, e[cnt++] = u; } scanf("%d", &ss); bfs(ss); for (int i = 1; i <= n; i++) { if (i != ss) { if (!dis[i]) printf("-1"); else printf("%d", dis[i]); if (i != n) printf(" "); } } printf("\n"); } return 0; }