搜索學習筆記
阿新 • • 發佈:2018-07-29
emp 並運算 namespace pso class 學習 memset 有向無環圖 能夠 搜索
搜索從零開始
搜索還是偏簡單的,知識點沒什麽,總結一些模板
代碼模板
- 添加邊
void add(int u,int v)
{
s[++len].u=u;
s[len].v=v;
s[len].next=head[u];
head[u]=len;
}
- DFS遍歷
void dfs(int u) { vis[u]=1; for(int i=head[u];i;i=s[i].next) { int v=s[i].v; if(vis[v]) continue; dfs(v); } }
- 樹的深度
void dfs(int u)
{
vis[u]=1;
for(int i=head[u];i;i=s[i].next)
{
int v=s[i].v;
if(vis[v]) continue;
dep[v]=dep[u]+1;
dfs(v);
}
}
- 樹的重心
void dfs(int u) { vis[u]=1; size[u]=1; int max_part=0; for(int i=head[u];i;i=s[i].next) { int v=s[i].v; if(vis[v]) continue; size[u]+=size[v]; max_part=max(max_part,size[v]); } max_part=max(max_part,n-size[u]); if(max_part<ans) { ans=max_part; pos=u; } }
- 圖的連通塊
void dfs(int u)
{
vis[u]=1;
for(int i=head[u];i;i=s[i].next)
{
int v=s[i].v;
if(vis[v]) continue;
dfs(v);
}
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
cnt++;
dfs(i);
}
}
- BFS遍歷
void bfs() { memset(dep,0,sizeof(dep)); queue<int> q; q.push(1); d[1]=1; while(q.size()) { int u=q.front; q.pop(); for(int i=head[u];i;i=s[i].next) { int v=s[i].v; dep[v]=dep[u]+1; q.push(v); } } }
- 拓撲搜索
void topsort()
{
queue<int>q;
for(int i=1;i<=n;i++){
b[i][i]=1;
if(ru[i]==0) q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=s[i].next)
{
int v=s[i].v;
ru[v]--;
b[v]|=b[u];
if(ru[v]==0) q.push(v);
}
}
}
EXAM搜索專題訓練
A.可達性統計
題解
給定一張N個點M條邊的有向無環圖,分別統計從每個點出發能夠到達的點的數量。因為求能到達多少個點具有後效性,所以我們要反向建圖。這裏用到了一個bitset,bitset能夠存儲二進制位,然後通過並運算就可以算出他到達了多少個點。因為是無環圖,遍歷時先從沒有子節點的點開始,用ru數組記錄有多少子節點,當子節點遍歷完了,可以從這個節點繼續向父節點遍歷。用到了拓撲搜索
#include <bits/stdc++.h>
const int maxn=30010;
using namespace std;
bitset<maxn> b[maxn];
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct node
{
int u;
int v;
int next;
}s[maxn<<2];
int len,head[maxn];
int n,m;
int ru[maxn];
void add(int u,int v)
{
s[++len].u=u;
s[len].v=v;
s[len].next=head[u];
head[u]=len;
}
void topsort()
{
queue<int>q;
for(int i=1;i<=n;i++){
b[i][i]=1;
if(ru[i]==0) q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=s[i].next)
{
int v=s[i].v;
ru[v]--;
b[v]|=b[u];
if(ru[v]==0) q.push(v);
}
}
}
int main()
{
read(n);
read(m);
int x,y;
for(int i=1;i<=m;i++){
read(x);
read(y);
add(y,x);
ru[x]++;
}
topsort();
for(int i=1;i<=n;i++){
out(b[i].count());
printf("\n");
}
return 0;
}
bitset用法:https://www.cnblogs.com/RabbitHu/p/bitset.html
搜索學習筆記