今天主要学习了图论算法知识里的强连通分量部分。代码模板基本都是一样的,关键是理解。理解之后就感觉简单多了。
主要是学会求连通分量的个数以及哪些点属于哪些连通分量。这里附上个人Tarjan算法模板代码:
void tar(int k)
{
low[k]=dfn[k]=++ti;
us[k]=1;
sta[++f]=k;
for(int i=he[k];i!=-1;i=a[i].nex)
{
int v=a[i].v;
if(!dfn[v])
{
tar(v);
low[k]=min(low[k],low[v]);
}
else if(us[v]) low[k]=min(low[k],dfn[v]);
}
if(low[k]==dfn[k])
{
cnt++;
do{
j=sta[f--];
us[j]=0;
sum[j]=cnt;
}while(j!=k);
}
}
void solve()
{
for(int i=1;i<=n;i++)
if(!dfn[i]) tar(i);//zhu yi!!!这里dfn注意清零
//cout<<cnt<<endl;
if(cnt!=1) puts("No");
else puts("Yes");
}
另外就是看了无向图求割顶与桥的模板,看了几个模板,存边都没用链式前向星,而是用的vector,不知道这对结果是否有什么影响。
下面附上例题poj 2117 求割顶数量的核心代码:
int dfs(int u,int fa)
{
int lowu;
pre[u]=lowu=++ti;
int cm=0;
for(int i=0;i<vc[u].size();i++)
{
int v=vc[u][i];
if(!pre[v])
{
cm++;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u]) ok[u]=1;//不要少了=,WA了一次,最后ok[i]=1即i为割顶
}
else if(pre[v]<pre[u]&&v!=fa)
lowu=min(lowu,pre[v]);
}
if(fa<0&&cm==1) ok[u]=0;
return low[u]=lowu;
}
目前准备多看几个博客和例题,争取理解透彻,能随时写出模板代码。
明天的主要任务是看无向图双连通分量的知识,总结一下,理解透彻原理及模板代码并正确熟练地敲出来,做几道经典例题。
一会儿去补昨天的EOJ月赛题目。。。