hdoj5876 補圖最短路 BFS+set維護還能夠更新的點.

這裏有一篇很棒的博客: http://blog.csdn.net/llzhh/article/details/52516591node

談談學到的東西:ide

1,set維護東西真的好用,好比維護還能更新的點spa

2,關於set的刪除  st.erase(iter).net

最後還要補充一下map和set的一點知識,就是若是你用erase刪除一個數字的時候,其實map和set封裝了紅黑樹在裏面,說白了就是個鏈表,可是網上好像是他們所用的空間是固定的,因此比通常的平衡樹效率要高,由於申請空間沒那麼費勁。那咱們從樹的角度出發,就是鏈表同樣,那麼若是你刪除了鏈表中一個節點,此時,再讓iter++尋找下一個節點,他是找不到的,由於那個節點已經被刪除了,本來節點空間裏面的東西全都是隨機生成的數字了,找下一個節點的時候都不知道飛到天上去了,那麼就會報錯。code

好比這樣blog

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按定位器刪除比按值刪除要快string

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

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
相關文章
相關標籤/搜索