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\n",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("\n");
83     }
84     return 0;
85 }
View Code

 

posted on 2018-02-06 16:54  Na_OH  阅读(141)  评论(0编辑  收藏  举报

导航