(1) 建图
邻接表
struct o
{
int y,v,next;//y:该边终点编号 v:权值 next:同起点下条边编号
}e[...];//边表
int lin[...];//起点表 lin[i]表示由i出去第一条边的下标
int len=0;//表示有len条边
void insert(int xx,int yy,int zz)
{
e[++len].next=lin[xx];
lin[xx]=len;
e[len].y=yy;
e[len].v=zz;
}
void init()
{
cin>>n>>m;
memset(e,0,sizeof(e));
memset(lin,0,sizeof(lin));
for(int i=1;i<=n;i++)
{
int xx,yy,zz;
cin>>xx>>yy>>zz;
insert(xx,yy,zz);
insert(yy,xx,zz);
}
}
(2) 遍历
1.邻接矩阵的dfs
void dfs(int k)
{
for(int i=1;i<=n;i++)
if(a[k][i] && !vis[i])
{
vis[i]=1;
dfs(i);
}
}
2.邻接表的dfs
void dfs(int k)
{
for(int i=lin[k];i;i=e[i].next)
if(!vis[e[i].y])
{
vis[e[i].y]=1;
dfs(e[i].y);
}
}
int main()
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
if(!vis[i])
dfs(i);
//求无向的连通分量
sumn=0;
for(int i=1;i<=n;i++)
if(!vis[i])
{
sumn++;
dfs(i);
}
cout<
3.邻接矩阵的bfs
void bfs(int i)
{
memset(q,0,sizeof(q));
int head=0,tail=1;
q[1]=i; vis[i]=1;
while(head
k=q[++head];
cout<
if(a[k][j] && !vis[j])
{
q[++tail]=j;
vis[j]=1;
}
}
}
4.邻接表的bfs
void bfs(int k)
{
int head=0,tail=1;
q[1]=k;
while(head++
for(int i=link[q[head]];i;i=a[i].next)
if(!vis[a[i].y])
{
vis[a[i].y]=1;
q[++tail]=a[i].y;
}
}
}
(3) 最短路
1.dijistra//不用堆优化
for(int i=1;i<=n;i++)
dis[i]=a[st][i];
memset(vis,0,sizeof(vis));
vis[st]=1;
dis[st]=0;
for(int _=1;_
int min=MAXX,mini;
for(int i=1;i<=n;i++)
if(!vis[i] && dis[i]
if(!k) break;
vis[k]=1;
for(int i=1;i<=n;i++)
if(!vis[i]&&dis[i]>dis[mini]+a[mini][i])
dis[i]=dis[mini]+a[mini][i];
}
//用堆优化
typedef pair
priority_queue
memset(dis,20,sizeof(dis));
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty())
{
pii t=q.top();q.pop();
int x=t.second,vv=t.first;
if(vis[x]) continue;
vis[x]=1;
for(int i=linkk[x];i;i=e[i].next)
if(dis[e[i].y]>vv+e[i].v)
{
dis[e[i].y]=vv+e[i].v;
q.push(make_pair(dis[e[i].y],e[i].y));
}
}
2.SPFA
memset(vis,0,sizeof(vis));
queue
q.push(st);
dis[st]=0;
vis[st]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=linkk[x];i;i=e[i].next)
if(dis[e[i].y]>dis[x]+e[i].v)
{
dis[e[i].y]=dis[x]+e[i].v;
if (!vis[e[i].y])
q.push(e[i].y),vis[e[i].y]=1;
}
}
3.floyed
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
(4)最小生成树
1.Kruskal 2.Prim (5)拓扑排序
void getfa(int x)
{
if(x==fa[x])
return x;
return fa[x]=getfa(fa[x]);
}
sort(e+1,e+len+1,mycmp(x.v
{
int x=getfa(e[i].x),y=getfa(e[i].y);
if(x!=y)
fa[x]=y,ans+=e[i].v;
}
cout<
void Prim()
{
int now=1;
memset(dis,20,sizeof(dis));
for(int i=linkk[1];i;i=e[i].next)
dis[e[i].y]=min(dis[e[i].y],e[i].v);
for (int _=1;_
int minn=MAXX;
vis[now]=1;
for(int i=1;i<=n;i++)
if(!vis[i]&&minn>dis[i])
minn=dis[i],now=i;
ans+=minn;
for(int i=linkk[now];i;i=e[i].next)
if(!vis[e[i].y]&&dis[e[i].y]>e[i].v)
dis[e[i].y]=e[i].v;
}
}
void topo()
{
int i,j,now;
queue
for(i=1;i<=n;i++)
if(!ind[i])
q.push(i);
while(!q.empty())
{
now=q.front();
q.pop();
ans[++cnt]=now;
for(i=last[now];i;i=e[i].next)
{
ind[e[i].to]--;
if(!ind[e[i].to])
q.push(e[i].to);
}
}
if(cnt!=n)
puts("-1");
else
for(i=1;i<=n;i++)
cout<
(6)树的直径
void bfs(int s)
{
int i,j,now;
queue
memset(v,0,sizeof(v));
memset(dis,0,sizeof(dis));
q.push(s); v[s]=1;
while(!q.empty())
{
now=q.front();
q.pop();
for(i=last[now];i;i=e[i].next)
if(!v[e[i].to])
{
v[e[i].to]=true;
dis[e[i].to]=dis[now]+e[i].v;
q.push(e[i].to);
}
}
for(i=1,ans=0;i<=n;i++)
if(dis[i]>ans)
{
ans=dis[i];
point=i;
}
}
int main()
{
bfs(s); bfs(point);
}
(7)树的重心
void dp(int x,int fa)
{
size[x]=1;
for(int i=0;i
int y=e[x][i];
if(y==fa)
continue;
dp(y,x);
size[x]+=size[y];
mx[x]=max(mx[x],size[y]);
}
mx[x]=max(mx[x],n-size[x]);
if(mx[x]
if(mx[x]==mx[ans] && x
}
(8)基环树
void getloop(int u)
{
vis[u]=++vs;
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==fa[u])
continue;
if(vis[v])
{
if(vis[v]
loop[++cnt]=v;
for(;v!=u;v=fa[v])
loop[++cnt]=fa[v];
}
else
fa[v]=u,getloop(v);
}
}
(9)最近公共祖先
1.倍增法
void dfs(int u,int d)
{
depth[u]=d;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa[0][u])
continue;
fa[0][v]=u;
dfds(v,d+1);
}
return ;
}
void init()
{
fa[0][1]=-1;
dfs(1,0);
for(int i=1;1< {
for(int j=1;j<=n;j++)
{
if(fa[i-1][j]<0)
fa[i][j]=-1;
else
fa[i][j]=fa[i-1][fa[i-1][j]];
}
}
return ;
}
int lca(int u,int v)
{
if(depth[u]>depth[v])
swap(u,v);
for(int d=depth[v]-depth[u],i=0;d;d>>=1,i++)
if(d&1) v=fa[i][v];
if(u==v) return u;
for(int i=max_logn-1;i>=0;i--)//max_logn=20 / 21
if(fa[i][u]!=fa[i][v])
{
u=fa[i][u];
v=fa[i][v];
}
return fa[0][u];
}
2.tarjan
int find(int x)
{
int y=x;
while(set[y].parent!=y)
y=set[y].parent;
while(x!=y)
{
int temp=set[x].parent;
set[x].parent=y;
x=temp;
}
return y;
}
void tarjan(int u)
{
vis[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(vis[v]) continue;
tarjan(v);
fa[v]=u;
}
for(int i=h[u];i!=-1;i=arr[i].next)
{
v=arr[i].to;
if(vis[v])
ans[arr[i].id]=find(v);
}
return ;
}