题意:给一个无向图以及一个点s,求在其补图点 s 到其他n-1个点的最短距离解:利用原图求补图上的最短路,bfs遍历,U到 与U的不邻接的点的边即为补图的一条边,可以直接计算出 到这些不邻接的点距离,dis[v']=dis[u]+1;然后将这些不邻接的点加入队列,继续寻找,用两个集合,,一个记录不邻接的点,一个记录没有用过的点
跟之前写的四川省赛一样一样的,我tm又用map超时了。。。
#include <set> #include <map> #include <stack> #include <queue> #include <deque> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-9 #define maxn 200100 #define MOD 1000000007 struct Edge { int to,next; }edge[maxn]; int n,m; int ans[maxn]; int tot,head[maxn]; void add_edge(int u,int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void bfs(int x) { queue<int> q; q.push(x); ans[x] = 0; set<int> s1,s2; set<int> ::iterator it; for(int i = 1; i <= n; i++) if(i != x) s1.insert(i); while(!q.empty()) { int u = q.front(); q.pop(); for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(!s1.count(v)) continue; s1.erase(v); s2.insert(v); } for(it = s1.begin(); it != s1.end(); it++) { q.push(*it); ans[*it] = ans[u] + 1; } s1.swap(s2); s2.clear(); } } int main() { int t,C = 1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); tot = 0; memset(head,-1,sizeof(head)); memset(ans,-1,sizeof(ans)); for(int i = 0; i < m; i++) { int x,y; scanf("%d%d",&x,&y); add_edge(x,y); add_edge(y,x); } int x; scanf("%d",&x); bfs(x); for(int i = 1; i < n; i++) if(i != x) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }