【BZOJ】[JSOI2008]星球大戰starwar

來源:互聯網
上載者:User

標籤:超級   esc   包括   arw   特殊   can   倒序   直接   速度   

Description

  很久以前,在一個遙遠的星系,一個黑暗的帝國靠著它的超級武器統治者整個星系。某一天,憑著一個偶然的
機遇,一支反抗軍摧毀了帝國的超級武器,並攻下了星系中幾乎所有的星球。這些星球通過特殊的以太隧道互相直
接或間接地串連。 但好景不長,很快帝國又重新造出了他的超級武器。憑藉這超級武器的力量,帝國開始有計劃
地摧毀反抗軍佔領的星球。由於星球的不斷被摧毀,兩個星球之間的通訊通道也開始不可靠起來。現在,反抗軍首
領交給你一個任務:給出原來兩個星球之間的以太隧道連通情況以及帝國打擊的星球順序,以盡量快的速度求出每
一次打擊之後反抗軍佔據的星球的連通快的個數。(如果兩個星球可以通過現存的以太通道直接或間接地連通,則
這兩個星球在同一個連通塊中)。

Input

  輸入檔案第一行包含兩個整數,N (1  < =  N  < =  2M) 和M (1  < =  M  < =  200,000),分別表示星球的
數目和以太隧道的數目。星球用 0 ~ N-1的整數編號。接下來的M行,每行包括兩個整數X, Y,其中(0 < = X <> 
Y 表示星球x和星球y之間有“以太”隧道,可以直接通訊。接下來的一行為一個整數k,表示將遭受攻擊的星球的
數目。接下來的k行,每行有一個整數,按照順序列出了帝國軍的攻擊目標。這k個數互不相同,且都在0到n-1的範
圍內。

Output

第一行是開始時星球的連通塊個數。接下來的K行,每行一個整數,表示經過該次打擊後現存星球
的連通塊個數。

Sample Input8 13
0 1
1 6
6 5
5 0
0 6
1 2
2 3
3 4
4 5
7 1
7 2
7 6
3 6
5
1
6
3
5
7Sample Output1
1
1
2
3
3--------------------------------------------------------------------------------------------------------------------------------- 題意:刪一些點,求連通分量分析:首先看到道路想到並查集,但並查集只能並,不能做到刪,這就需要我們把題目中給的刪通過離線後的逆序處理變成添邊,如果刪  1 , 2 , 3 三個點,那麼可以轉換成添加 3 , 2, 1三個點(倒序)。使用vector存邊,那麼就可以對於每個點的所有邊進行輕鬆的並操作。結構:讀入    ->    求開始時的連通分量,連接所有不會被刪掉的邊    ->    倒序(之前預先處理了也可以)更新   ->   輸出
  1 #include <cstdio>  2 #include <vector>  3 #include <algorithm>  4 using namespace std;  5 const int maxn=400005;  6 vector <int> e[maxn];  7 int pa[maxn],rank[maxn],x[maxn],d[maxn],num[maxn];  8 void init(int n)  9 { 10     for(int i=1;i<=n;i++) 11     { 12         pa[i]=i; 13     } 14 } 15 int find(int x) 16 { 17     if(pa[x]==x) return x; 18     else return pa[x]=find(pa[x]); 19 } 20 void unite(int x,int y) 21 { 22     x=find(x); 23     y=find(y); 24     if(x==y) return;  25     if(rank[x]>rank[y]) pa[y]=x; 26     else 27     { 28         pa[x]=y; 29         if(rank[x]==rank[y]) rank[x]++; 30     } 31 } 32 bool same(int x,int y) 33 { 34     return find(x)==find(y); 35 } 36 int main() 37 { 38     int n,m,Ans=0,a,b; 39     scanf("%d%d",&n,&m); 40     init(n); 41     for(int i=1;i<=m;i++) 42     { 43         scanf("%d%d",&a,&b); 44         a++; 45         b++;//序號從0開始  46         e[a].push_back(b); 47         e[b].push_back(a); 48     } 49     int k; 50     scanf("%d",&k); 51      52     //離線倒處理  53     for(int i=1;i<=k;i++) 54     { 55         scanf("%d",&x[k-i+1]); 56         x[k-i+1]++;//序號從0開始  57         d[x[k-i+1]]=1; 58     } 59      60     //開始時連通分量數  61     for (int i=1;i<=n;i++) 62         if (d[i]==0) 63             for (int j=0;j<e[i].size();j++) 64             { 65                 int v=e[i][j]; 66                 if (d[v]==0) 67                     unite(i,v); 68             } 69     for (int i=1;i<=n;i++) 70     { 71         if((find(i)==i)&&(d[i]==0)) 72             Ans++; 73     } 74      75     //更新  76     for(int i=1;i<=k;i++) 77     { 78         int u=x[i]; 79         d[u]=0; 80         num[i]=Ans; 81         Ans++; 82         for(int j=0;j<e[u].size();j++) 83         { 84             int v=e[u][j]; 85             if(d[v]==0) 86             { 87                 if(!same(u,v)) 88                 { 89                     unite(u,v); 90                     Ans--; 91                 } 92             } 93         } 94     } 95     num[k+1]=Ans; 96     for(int i=k+1;i>=1;i--) 97     { 98         printf("%d\n",num[i]); 99     }100     return 0;101 }

 

【BZOJ】[JSOI2008]星球大戰starwar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.