补图BFS(hdu 5876)

题目大意:

给出一个图和起点S,求补图中S到其他点的最短距离。

http://acm.hdu.edu.cn/showproblem.php?pid=5876

 

我自己的垃圾做法:

用线段树来维护dijkstra的dis数组。每次取出dis最小的点来更新其他点。 假设x连出去的边是y1 < y2 < y3 ... < yk.  那么对于dis[1, y1 - 1] [y1 + 1, y2 - 1] [y2 + 1, y3 - 1]...这些区间做区间取min操作。 比较容易出错的的地方是每次用x更新完其他点,需要把dis[x] 设置成INF, 对于一个区间,如果最小值就是INF,说明这个区间里的点都被扩展过了,直接return,而不能对它做取min操作。   因为需要做的取min操作是O(m)的,所以总的复杂度是O(mlogn).

 

简单做法:

用一个set维护哪些点还没被BFS到。 每次从队列取出一个点x, 然后把set里的点分成两类,一类是和x在原图中有边相连,一类是没有边相连,把和x没有边相连的点从set中删去,加入队列。  总的复杂度是O(mlogn)

 

参考代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")#include <bits/stdc++.h>
 2 //zoj 3496
 3 #include <bits/stdc++.h>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 #define X first
 8 #define Y second
 9 #define MAXN 200020
10 #define M 105
11 const int mod = 1e9 + 7;
12 const int INF = 1e9 + 10;
13 
14 vector<int> E[MAXN];
15 int d[MAXN];
16 queue<int> Q;
17 set<int> st, tmp;
18 
19 
20 void BFS(int S, int n)
21 {
22       Q.push(S); d[S] = 0;
23       for (int i = 1; i <= n; ++i)
24            if (i != S) st.insert(i);
25      while (!Q.empty())
26      {
27          int x = Q.front(); Q.pop();
28          tmp.erase(tmp.begin(), tmp.end());
29          for (auto y: E[x])
30          {
31               if (st.find(y) != st.end())
32                   tmp.insert(y);
33         }
34         for (auto v: st) if (tmp.find(v) == tmp.end()) Q.push(v), d[v] = d[x] + 1;
35         st = tmp;
36      }    
37      bool flag = false;
38      for (int i = 1; i <= n; ++i)
39      {
40           if (i == S) continue;
41           if (flag) printf(" ");
42           printf("%d", d[i]);
43           flag = true;
44      }
45      printf("\n");
46 }
47 
48 int main() 
49 {
50     //freopen("input", "r", stdin);
51     //freopen("output", "w", stdout);
52     
53     int T, n, m;
54     scanf("%d", &T);
55     while (T--)
56     {
57         scanf("%d %d", &n, &m);
58         for (int i = 1; i <= m; ++i)
59         {
60             int x, y;
61             scanf("%d %d", &x, &y);
62             E[x].push_back(y);
63             E[y].push_back(x);
64         }
65         int S;
66         scanf("%d", &S);
67         for (int i = 1; i <= n; ++i) d[i] = -1;
68         BFS(S, n);
69         for (int i = 1; i <= n; ++i) E[i].clear();
70     } 
71 
72     return 0; 
73 } 

 

posted @ 2017-09-22 23:17  lzw4896s  阅读(297)  评论(0编辑  收藏  举报