鏈表加bfs求補圖聯通塊

來源:互聯網
上載者:User

標籤:鏈表   迴圈   span   pop   探索   int   聯通   分享圖片   入隊   

https://oj.neu.edu.cn/problem/1387

給一個點數N <= 100000, 邊 <= 1000000的無向圖,求補圖的聯通塊數,以及每個塊包含的點數

由於點數太大,補圖會是稠密圖,甚至建立補圖都要O(n^2),只能挖掘一下聯通塊,bfs,補圖的性質,從原圖入手求補圖的聯通塊:

 

在原圖中不直接相鄰的點,在補圖中一定屬於同一個聯通塊

每個點只屬於一個聯通塊,所以找好一個聯通塊之後可以刪去這個聯通塊的所有點,把圖規模縮小

 

這樣子:1.準備一個集合放所有未探索的點,初始化時將1~N放進去

2.從集合中取一點放入隊列(新的聯通塊)

3.當隊列不為空白時,從隊列中取一個點u並彈出,將原圖中與u直接相連的點標記;遍曆集合,將在集合中的(即未探索的)並且未被標記的點(這些點屬於本聯通塊)入隊並從集合中刪去,將標記刪去。重複執行直到隊列為空白

4.集合不為空白轉2,為空白結束

考慮有刪除操作和時間問題,集合的實現當然是選擇鏈表,用數組實現的雙向鏈表即可 

 

最佳化有兩個:一是通過原圖找補圖的聯通塊;二是把搜過的點刪除,這樣每次找未標記的點時比起從1迴圈到N更優(常數最佳化(誤))

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<queue>using namespace std;const int maxn = 1e5+100, maxm = 1e6+100, inf = 0x3f3f3f3f;struct lnk{    int val;    int pre, nxt;}lk[maxn];struct edge{    int v, nxt;}e[maxm*2];int head[maxn], tot, block_cnt, n, m;int adj[maxn], vis[maxn], num[maxn];void addedge(int u, int v){    e[tot] = (edge){v, head[u]};    head[u] = tot++;}void dele(int x){    lk[lk[x].nxt].pre = lk[x].pre;    lk[lk[x].pre].nxt = lk[x].nxt;}void src(){    for(int i = 1; i <= n; i++){        vis[i] = adj[i] = 0;    }    queue<int>Q;    block_cnt = 0;    while(lk[0].nxt != -1){        //puts("blk++");        Q.push(lk[0].nxt);        //printf("take %d\n", lk[0].nxt);        vis[lk[lk[0].nxt].val] = 1;        dele(lk[0].nxt);        block_cnt++;        num[block_cnt] = 1;        while(!Q.empty()){            int x = Q.front();            x = lk[x].val;            //printf("%d\n", x);            Q.pop();            for(int i = head[x]; ~i; i = e[i].nxt){                int v = e[i].v;                adj[v] = 1;            }            for(int i = lk[0].nxt; ~i; i = lk[i].nxt){                int w = lk[i].val;                if(!vis[w] && !adj[w]){                    Q.push(w);                    vis[w] = 1;                    dele(i);                    num[block_cnt]++;                }            }            for(int i = head[x]; ~i; i = e[i].nxt){                int v = e[i].v;                adj[v] = 0;            }        }    }}int main(){    int t;    scanf("%d", &t);    while(t--){        scanf("%d%d", &n, &m);        for(int i = 1; i <= n; i++)            head[i] = -1;        tot = 0;        while(m--){            int u, v;            scanf("%d%d", &u, &v);            addedge(u, v);            addedge(v, u);        }        for(int i = 1; i <= n; i++){            lk[i].val = i;            lk[i].pre = i-1;            lk[i].nxt = i+1;        }        lk[n].nxt = -1;        lk[0].nxt = 1;        src();        sort(num+1, num+block_cnt+1);        printf("%d\n", block_cnt);        for(int i = 1; i <= block_cnt; i++){            printf("%d%c", num[i], i == block_cnt ? ‘\n‘ : ‘ ‘);        }    }    return 0;}/* 3 5 7 1 2 1 3 1 4 1 5 2 3 2 4 2 5 6 9 1 4 1 5 1 6 2 4 2 5 2 6 3 4 3 5 3 6 3 3 1 2 2 3 3 1 */
View Code

 

鏈表加bfs求補圖聯通塊

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.