题干:
In graph theory, the complementcomplement of a graph GG is a graph HH on the same vertices such that two distinct vertices of HH are adjacent if and only if they are notnotadjacent in GG.
Now you are given an undirected graph GG of NN nodes and MM bidirectional edges of unitunit length. Consider the complement of GG, i.e., HH. For a given vertex SS on HH, you are required to compute the shortest distances from SS to all N−1N−1 other vertices.
Input
There are multiple test cases. The first line of input is an integer T(1≤T<35)T(1≤T<35)denoting the number of test cases. For each test case, the first line contains two integers N(2≤N≤200000)N(2≤N≤200000) and M(0≤M≤20000)M(0≤M≤20000). The following MM lines each contains two distinct integers u,v(1≤u,v≤N)u,v(1≤u,v≤N) denoting an edge. And S (1≤S≤N)S (1≤S≤N)is given on the last line.
Output
For each of TT test cases, print a single line consisting of N−1N−1 space separated integers, denoting shortest distances of the remaining N−1N−1 vertices from SS (if a vertex cannot be reached from S, output ``-1" (without quotes) instead) in ascending order of vertex number.
Sample Input
1 2 0 1
Sample Output
1
题目大意:
给一个N个点M条边的无向图,给你一个圆点,让你在对应图的补图上求出起点S到每个点的最短路。
解题报告:
正常bfs是对于当前点来说枚举当前点的每一条边,看该点是否遍历过来决定是否进行入队操作。而对于这个题,因为补图的边的数量非常大,所以我们可以从点的角度入手,因为一共需要更新1e5个点,所以我们可以直接在每一次循环中都先枚举每一个点,看他和当前点是否有连边,如果原图中没有这条边的话那就可以直接更新这个点,并且把他放到队列中。通过枚举边变成枚举点,减少时间复杂度。也就是正常bfs是枚举每一个边看是否出点被更新过,这个题因为边数很多但是点数不多,所以可以枚举每一个没出现过的点,看这条边是否存在。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int MAX = 2e5 + 5;
set<int> ss;
set<int> vv[MAX];
int st,n,m;
int dis[MAX];
void bfs(int st) {for(int i = 1; i<=n; i++) dis[i] = INF;dis[st] = 0;ss.erase(st);queue<int> q;q.push(st);while(q.size()) {vector<int> tmp;int cur = q.front();q.pop();for(auto it = ss.begin();it!=ss.end(); ++it) {int v = *it;if(vv[cur].find(v) == vv[cur].end()) {dis[v] = dis[cur]+1;tmp.pb(v); q.push(v);} }for(auto v : tmp) ss.erase(v);}
}
int main()
{int T;cin>>T;while(T--) {scanf("%d%d",&n,&m);ss.clear();for(int i = 1; i<=n; i++) ss.insert(i);for(int i = 1; i<=n; i++) vv[i].clear();for(int u,v,i = 1; i<=m; i++) scanf("%d%d",&u,&v),vv[u].insert(v),vv[v].insert(u);scanf("%d",&st);bfs(st);int cnt = 1;for(int i = 1; i<=n; i++) {if(i == st) continue;if(dis[i] == INF) printf("%d%c",-1,cnt == n-1 ? '\n' :' ') ;else printf("%d%c",dis[i],cnt == n-1 ? '\n' :' ');cnt++;}}return 0 ;
}