• 补图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("
    ");
    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 } 
  • 相关阅读:
    极域电子教室 e-Learning Class V4 2010专业版 学生机 卸载方法
    浅谈IT员工管理
    apacheserver下载、安装、配置
    Android BLE开发之Android手机搜索iBeacon基站
    Qt编程18:Qt调色板QPalette的使用
    二叉树的操作
    Android应用开发多语言drawable目录
    Mybatis文档阅读笔记(明日继续更新...)
    《Spark快速大数据分析》—— 第六章 Spark编程进阶
    Java程序员的日常——SpringMVC+Mybatis开发流程、推荐系统
  • 原文地址:https://www.cnblogs.com/vb4896/p/7577642.html
Copyright © 2020-2023  润新知