1、模板題poj1611the suspects
每個組內的人,同乙個組內都是感染者,問與「0」號人有關的有多少人
#include #includeusing namespace std;
const int maxn = 1000100;
struct ds
void merge(int a,int b)
//x下邊的節點不用改,因為查詢的時候會自動更新
int main()
for(j=1;j<=m;++j)
else
merge(a,b);
}if(flag)
printf("scenario #%d:\nsuspicious bugs found!\n\n",i);
else
printf("scenario #%d:\nno suspicious bugs found!\n\n",i);
}return 0;
}
3、帶權並查集經典題:poj1182食物鏈
我說不明白==參考:
4、並查集水題 挨著就算相交,給定某個線段,詢問這一團的有多少個
#include#include#includeusing namespace std;
int pre[1010],sum[1010];
struct point;
struct edge edge[1010];
int e;//邊數
int find(int x)
void merge(int a,int b)
}double xmult(point a,point b,point c)
bool onsegment(point a,point b,point c)
bool cross(point a,point b,point c,point d)
int main()
,,,,
,,,,,,};
int f[300000],n,m;
char c;
int num[100][100];
void init(int n)
int find(int x)
int main()
void addto(int x,int y)
a[y]=a[x];
return ;
}void cal()
}}int main()
memset(vis,0,sizeof(vis));
for(int i=1;i<=100000;i++) a[i]=i;
mark=1;
count=0;
maxn=0;
// point=0;
addto(x,y);
vis[x]=1;
vis[y]=1;
if(maxn
這個題的題意晦澀難懂,總的做法就是每次將兩個集合合併(原來兩個點就在乙個集合內的不算)合併一次,乙個最開始是等於長度的變數--,最後對這個變數^26取模(快速冪)
#include #include#includeusing namespace std;
#define maxn 10000005
#define mod 1000000007
int f[maxn],n,m,l,r,count;
bool vis[maxn];
int find(int x)
void addto(int x,int y)
long long multi(int x)
return ans;
}int main()
/*for(int i=1;i<=n+1;i++)
*/printf("%lld\n",multi(n-count)%mod);
}return 0;
}
8、 第六個題剛剛說完圖論,這就來了==本題意在求出加入多少邊可以構成雙連通分量,而
構造雙連通分量的加邊數=(原圖的葉節點數+1)/2,用並查集縮點,列舉每個橋,[團]++,=1說明是葉子節點
#include #include #include #include #include using namespace std;
const int n=5006;
vectorg[n];
struct bridge
bg[2*n];
int vis[n],low[n],dfn[n],time;
int fa[n],deg[n];
int n,m,cnt;
void init()
}else
low[u] = min(low[u],dfn[v]);
}}int main()
void addto(int x,int y)
a[y]=a[x];
num[x]+=num[y];
return ;
}int main()
for(int i=1;i
題意:給出乙個圖,問幾筆畫才能經過所有邊
連通圖有乙個性質:其需要畫的筆數=度數為奇數的點數除以2,那麼由於給出的圖並沒有說明是否是連通圖,我們需要用並查集來維護連通圖,並且忽略單點的「子圖」 所以說就和第8題一樣了
#include #include#include#includeusing namespace std;
int a[100005],deg[100005],odd[100005];
bool used[100005];
int fnd(int x)
void addto(int x,int y)
a[y]=a[x];
return ;
}int main()
for(int i=0;iv;
for(int i=1;i<=n;i++)
if(deg[i]&1)
odd[f]++;
}cnt=0;
for(int i=0;i
本來還有兩個題的,離線版的lca和左偏堆,
和並查集的關係不大,就沒寫
並查集 總結
自己學完後總結一下吧,並查集,我的理解就是乙個查詢與合併,用乙個find函式來查詢自己的祖先也就是根節點,在這過程中還可以進行路徑壓縮,就是讓這個點直接變到根節點之下,還有就是合併,找出這兩個點的根節點,如果根節點不相同的話,就將乙個根節點放到另乙個根節點下面。這道題的就是用並查集做,找出總共有幾個...
並查集總結
用自己的理解來寫好了 有些地方可能不對 不定時更新理解 操作主要為三步 一 初始化 void init 二 查詢 這個為路徑壓縮 就是每次查詢時更新 查詢節點 x 上面所有節點直接使他們連向根節點 每次查詢更新 int find int x 另一種路徑壓縮 不過麻煩了些 作為理解 int find ...
並查集總結
注 此博文是在老師上課之後總結的,屬於課堂筆記,大部分摘自老師提供的課件。並查集總結總結兩點就是 並 和 查 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組...