题意:
给你一个图G,问补图上s到其他n-1个点的最短路。
题解:
bfs + set。每次把u点不相连的点入队列,取更新。具体见代码。
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for(int i = a; i <= n; ++ i);
#define per(i, a, n) for(int i = n; i >= a; -- i);
typedef long long ll;
const int N = 2e5+ 5;
const int mod = 998244353;
const double Pi = acos(- 1.0);
const int INF = 0x3f3f3f3f;
const int G = 3, Gi = 332748118;
ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b);}
bool cmp(int a, int b){ return a > b;}
//
int T, n, m, s;
int head[N], cnt = 0;
int dis[N];
queue<int> q;
set<int> ta, tb;
struct node{
int to, nxt;
}edge[N << 1];
void add(int u, int v){
edge[cnt].to = v, edge[cnt].nxt = head[u], head[u] = cnt ++;
edge[cnt].to = u, edge[cnt].nxt = head[v], head[v] = cnt ++;
}
void bfs(){
while(q.size()) q.pop();
set<int>::iterator it;
ta.clear(), tb.clear();
dis[s] = 0;
for(int i = 1; i <= n; ++ i) ta.insert(i);
ta.erase(s);
q.push(s);
while(q.size()){
int u = q.front(); q.pop();
for(int i = head[u]; i != -1; i = edge[i].nxt){
int v = edge[i].to;
if(!ta.count(v)) continue;
ta.erase(v);
tb.insert(v);
}
for(it = ta.begin(); it != ta.end(); ++ it){
q.push(*it);
dis[*it] = dis[u] + 1;
}
ta = tb;
tb.clear();
}
}
int main()
{
scanf("%d",&T);
while(T --){
cnt = 0;
scanf("%d%d",&n,&m);
for(int i = 0; i <= n; ++ i) head[i] = -1;
for(int i = 1; i <= m; ++ i){
int x, y; scanf("%d%d",&x,&y);
add(x, y);
}
scanf("%d",&s);
bfs();
int num = 0;
for(int i = 1; i <= n; ++ i){
if(i == s) continue;
num ++;
if(dis[i] == INF) printf("-1");
else printf("%d",dis[i]);
if(num == n - 1) printf("
");
else printf(" ");
}
}
return 0;
}