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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

poj1988(判断一个结点下面有多少个结点,推荐)

發(fā)布時間:2025/4/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj1988(判断一个结点下面有多少个结点,推荐) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題意:有n個元素,開始每個元素自己一棧,有兩種操作,將含有元素x的棧放在含有y的棧的頂端,合并為一個棧。第二種操作是詢問含有x元素下面有多少個元素。

?

6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
輸出:

?

1 0 2

思路:這道題,說不上很難,額,解決它也的確花了比較長的時間。詢問x元素下面有多少個元素,那么我只需要統(tǒng)計x元素上面有多少個元素,再用x所在的并查集的根節(jié)點的元素個數(shù)減去x元素上面的元素個數(shù),
結(jié)果就出來了......當(dāng)然,還是有些細(xì)節(jié)地方要說說的,在路徑壓縮的時候,有個rang[][3],其中rank[x][0],代表元素x上面有多少個元素,rank[x][1]代表元素x下面有多少個元素,rank[x][2]判斷x元素
是否為某個子并查集的根節(jié)點。
如果某個結(jié)點x的父親結(jié)點y曾經(jīng)為某一個子并查集的根節(jié)點,那么,說明對于這個結(jié)點x已經(jīng)是在y為根節(jié)點的時候壓縮過了,那么當(dāng)y不為根節(jié)點了,就不必再重新x對y的路徑了,只需要直接更新,x對于新的根節(jié)點的路徑
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int father[30005],rank[30005][3]; int flag=0; int find(int x) {if(rank[x][0]==0)rank[x][2]=1;if(x==father[x])return x;int tmp=father[x];father[x]=find(father[x]);int root=father[x];if(tmp==root){rank[root][1]+=rank[x][1];rank[x][1]=0;//if(rank[root])/*if(flag==1){printf("1: %d %d %d %d\n",x,tmp,rank[x][0],rank[tmp][0]);}*/}else{rank[root][1]+=rank[x][1];rank[x][1]=0;if(rank[tmp][2]==1) //曾經(jīng)為某一顆子并查集的根結(jié)點,那么它下面的結(jié)點直接+上根節(jié)點的值就是rank[x][0]+=rank[tmp][0];elserank[x][0]=rank[tmp][0]+1;/*if(flag==1){printf("2: %d %d %d %d\n",x,tmp,rank[x][0],rank[tmp][0]);}*/}return root; } void liantong(int tmp,int tmp1) {int x=find(tmp);int y=find(tmp1);father[y]=x;rank[y][0]=rank[x][1];rank[x][1]+=rank[y][1];rank[y][1]=0; } int main() {int n;scanf("%d",&n);{for(int i=0; i<=30001; i++){father[i]=i;rank[i][0]=0;rank[i][1]=1;rank[i][2]=0;}while(n--){char ch[10];scanf("%s",ch);if(ch[0]=='M'){int tmp,tmp1;scanf("%d%d",&tmp,&tmp1);int x=find(tmp);int y=find(tmp1);if(x!=y)liantong(tmp,tmp1);// find(tmp);// find(tmp1);}else{int k;scanf("%d",&k);if(k==17)flag=1;int ans=rank[find(k)][1];/*if(rank[k][0]==0)printf("%d\n",rank[k][1]-1);else*/printf("%d\n",ans-rank[k][0]-1);}}}return 0; } /* 110 M 12 14 M 15 16 M 16 17 M 12 17 C 17 */

?

總結(jié)

以上是生活随笔為你收集整理的poj1988(判断一个结点下面有多少个结点,推荐)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。