日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)

發布時間:2025/3/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

在遙遠的S星系中一共有N個星球,編號為1…N。其中的一些星球決定組成聯盟,以方便相互間的交流。
但是,組成聯盟的首要條件就是交通條件。初始時,在這N個星球間有M條太空隧道。每條太空隧道連接兩個星球,使得它們能夠相互到達。若兩個星球屬于同一個聯盟,則必須存在一條環形線路經過這兩個星球,即兩個星球間存在兩條沒有公共隧道的路徑。
為了壯大聯盟的隊伍,這些星球將建設P條新的太空隧道。這P條新隧道將按順序依次建成。一條新軌道建成后,可能會使一些星球屬于同一個聯盟。你的任務是計算出,在一條新隧道建設完畢后,判斷這條新軌道連接的兩個星球是否屬于同一個聯盟,如果屬于同一個聯盟就計算出這個聯盟中有多少個星球。

Input

第1行三個整數N,M和P,分別表示總星球數,初始時太空隧道的數目和即將建設的軌道數目。
第2至第M+1行,每行兩個整數,表示初始時的每條太空隧道連接的兩個星球編號。
第M+2行至第M+P+1行,每行兩個整數,表示新建的太空隧道連接的兩個星球編號。這些太空隧道按照輸入的順序依次建成。

Output

輸出共P行。如果這條新的太空隧道連接的兩個星球屬于同一個聯盟,就輸出一個整數,表示這兩個星球所在聯盟的星球數。如果這條新的太空隧道連接的兩個星球不屬于同一個聯盟,就輸出”No”(不含引號)。

Sample Input

輸入1:

3 2 1
1 2
1 3
2 3

輸入2:

5 3 4
1 2
4 3
4 5
2 3
1 3
4 5
2 4

Sample Output

輸出1:

3

輸出2:

No
3
2
5

Data Constraint

對于 10% 的數據有 1N,M,P100
對于 40% 的數據有 1N,M,P2000
對于 100% 的數據有 1N,M,P200000

Hint

Solution

  • 這一題是運用并查集的典例,使用靈活。

  • 首先對所有邊逐一處理,如果連了邊之后不會形成環,就直接連邊,否則打一個標記(不連)

  • 其中可以用并查集維護兩個端點是否屬于同一個集合

  • 以后處理出森林的每個點的父親節點和深度

  • 然后就開始處理未連的邊,對于兩個端點,

  • 像找最近公共祖先一樣,逐個逐個往上走,途中維護累加環的大小即可

  • 總時間復雜度 O(M+P)

Code

#include<cstdio> using namespace std; const int N=500001; struct data {int x,y; }edge[N]; int tot,num,f1,f2; int f[N],g[N]; int fa[N],dep[N]; int first[N],next[N*4],en[N*4]; bool bz[N]; inline int read() {int data=0; char ch=0;while(ch<'0' || ch>'9') ch=getchar();while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();return data; } inline int get(int x) {return (f[x]==x)?x:f[x]=get(f[x]); } inline void insert(int x,int y) {next[++tot]=first[x];first[x]=tot;en[tot]=y; } inline void dfs(int x,int y) {dep[x]=dep[fa[x]=y]+1;for(int i=first[x];i;i=next[i])if(en[i]!=y) dfs(en[i],x); } inline void work(int v) {f1=edge[v].x,f2=edge[v].y;while(true){f1=get(f1),f2=get(f2);if(f1==f2) return;if(dep[f1]>dep[f2]){g[f[f1]=f2]+=g[f1];g[f1]=0;f1=fa[f1];}else{g[f[f2]=f1]+=g[f2];g[f2]=0;f2=fa[f2];}} } int main() {int n=read(),m=read(),p=read();for(int i=1;i<=n;i++) f[i]=i;for(int i=1;i<=m+p;i++){f1=get(edge[i].x=read());f2=get(edge[i].y=read());if(f1!=f2){f[f1]=f2;insert(edge[i].x,edge[i].y);insert(edge[i].y,edge[i].x);bz[i]=true;}}for(int i=1;i<=n;i++)if(!dep[i]) dfs(i,0);for(int i=1;i<=n;i++) g[f[i]=i]=1;for(int i=1;i<=m;i++)if(!bz[i]) work(i);for(int i=m+1;i<=m+p;i++)if(!bz[i]){work(i);printf("%d\n",g[f1]);}else printf("No\n");return 0; }

總結

以上是生活随笔為你收集整理的JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。