• hdoj5876 补图最短路 BFS+set维护还可以更新的点.


    这里有一篇很棒的博客: http://blog.csdn.net/llzhh/article/details/52516591

    谈谈学到的东西:

    1,set维护东西真的好用,比如维护还能更新的点

    2,关于set的删除  st.erase(iter)

    最后还要补充一下map和set的一点知识,就是如果你用erase删除一个数字的时候,其实map和set封装了红黑树在里面,说白了就是个链表,但是网上好像是他们所用的空间是固定的,所以比一般的平衡树效率要高,因为申请空间没那么费劲。那我们从树的角度出发,就是链表一样,那么如果你删除了链表中一个节点,此时,再让iter++寻找下一个节点,他是找不到的,因为那个节点已经被删除了,原本节点空间里面的东西全都是随机生成的数字了,找下一个节点的时候都不知道飞到天上去了,那么就会报错。

    比如这样

    1 for(iter = Set.begin(); iter != Set.end(); iter++)  
    2 {  
    3     if(!mark[*iter])  
    4     {  
    5         dist[*iter] = dist[now] + 1;  
    6         q.push(*iter);  
    7         Set.erase(iter);  
    8     }  
    9 }  

    这样的写法是错误的,因为先删除节点,后++,此时++指向的就不是下一个节点了,所以我们要在删除前就++,来指向下一个节点。也就是我写的程序那样

     1 for(iter = Set.begin(); iter != Set.end(); )  
     2 {  
     3     if(!mark[*iter])  
     4     {  
     5         dist[*iter] = dist[now] + 1;  
     6         q.push(*iter);  
     7         Set.erase(iter++);  
     8     }  
     9     else  
    10         iter++;   
    11 }  

    这样就可以不报错且正确了,完。

    3,另外感觉,set按定位器删除比按值删除要快

    4,一个剪枝,if(st.empty())break;

    5,不好操作时,我们可以把将要删除的东西放在一个队列里,等遍历完后再进行按值删除.

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<set>
     5 using namespace std;
     6 const int MAXV=5e5+7,MAXE=5e5+7;
     7 int V,E;
     8 struct edge{
     9     int next,v;
    10 }es[MAXE*2];
    11 int tot,head[MAXV];
    12 void init(){
    13     tot=0;
    14     memset(head,-1,sizeof(head));
    15 }
    16 void addEdge(int u,int v){
    17     es[tot].v=v;
    18     es[tot].next=head[u];
    19     head[u]=tot++;
    20 }
    21 int d[MAXV];
    22 struct node{
    23     int u,step;
    24 }s;
    25 int mp[MAXV];
    26 queue<node>q;
    27 set<int>st;
    28 void bfs(int S){
    29     while(!q.empty())q.pop();
    30     st.clear();
    31 
    32     for(int i=1;i<=V;++i)if(i!=S)st.insert(i);
    33     s.u=S;
    34     s.step=0;
    35      d[S]=0;
    36     q.push(s);
    37 
    38     while(!q.empty()){
    39         node no=q.front();q.pop();
    40         int u=no.u;
    41     //    printf("u=%d
    ",u);
    42         for(int i=head[u];~i;i=es[i].next){
    43             int v=es[i].v;
    44             mp[v]=1;
    45         }
    46 
    47         for(auto i=st.begin();i!=st.end();){
    48             if(!mp[*i]){
    49                 if(d[*i]!=-1)continue;
    50                 node ne;
    51                 ne.step=no.step+1;
    52                 ne.u=*i;
    53                 d[*i]=ne.step;
    54                 q.push(ne);
    55                 st.erase(i++);
    56             }else mp[*i]=0,i++;
    57         }
    58         if(st.empty())break;
    59     }
    60 }
    61 int main(){
    62     int T;scanf("%d",&T);
    63     while(T--){
    64         scanf("%d%d",&V,&E);
    65         init();
    66         for(int i=0;i<E;++i){
    67             int a,b;scanf("%d%d",&a,&b);
    68             addEdge(a,b);
    69             addEdge(b,a);
    70         }
    71         int S;scanf("%d",&S);
    72         memset(d,-1,sizeof(d));
    73         memset(mp,0,sizeof(mp));
    74         bfs(S);
    75         bool flag=true;
    76         for(int i=1;i<=V;++i){
    77             if(d[i]!=0){
    78                 printf(flag?"%d":" %d",d[i]);
    79                 flag=false;
    80             }
    81         }
    82         printf("
    ");
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    anaconda环境---ubuntu下重装
    算法---Face_Recognition配置实战篇
    算法---FaceNet+mtcnn的使用记录
    算法---FaceNet理论学习篇
    算法---FaceNet在Tf下的实战篇
    ubuntu系统---切换Py2.X与Py3.X版本
    anaconda环境中---py2.7下安装tf1.0 + py3.5下安装tf1.5
    Git---初入开源代码管理库的学习过程003
    day 87 Vue学习六之axios、vuex、脚手架中组件传值
    day 86 Vue学习之五DIY脚手架、webpack使用、vue-cli的使用、element-ui
  • 原文地址:https://www.cnblogs.com/sun-yinkai/p/8423102.html
Copyright © 2020-2023  润新知