对博客美化的尝试

随手粘一个以前oi时期的博文看看效果

今天考试T1考这个,以前只在床上看书时推过一遍,现在忘完了。 复习(重学)一下。

学习博客:

CSDN

OIWIKI

DFS 树

树枝边:DFS时经过的边,即DFS搜索树上的边。

前向边:与DFS方向一致,从某个结点指向其某个子孙的边。

后向边:与DFS方向相反,从某个结点指向其某个祖先的边。(返祖边)

横叉边:从某个结点指向搜索树中的另一子树中的某结点的边。

强联通分量

直接写过程,证明抽象式理解即可(busi)。

DFS的时候:

  1. \(v\) 未被访问,常规操作加更新 \(low\) ,同时入栈。

  2. \(v\) 被访问过了,用它来回溯更新 \(low\)

回溯的时候:

如果 \(dfn[x]==low[x]\) ,就弹出它及以上的为一个 \(SCC\)

抽象式证明:

当它能回到以前的时候,因为 \(low\) 被更新了,所以不会出栈。如果是单个 \(SCC\) 的话,那么就先出栈了,就无需考虑了。

例题(以前做过的就不写了):

P1407 稳定婚姻

唯一要关注的是建图的关系 (可怕),写在代码里了。

#include<bits/stdc++.h>

using namespace std;

const int MX=4*10000+10;
#define LL long long
#define inf 0x3f3f3f3f

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

int n,m;

unordered_map<string,int> mp;
int mp_idx=0;

inline int _hash(string s)
{
	if(!mp[s])
	{
		mp[s]=++mp_idx;
		return mp_idx;
	}
	else return mp[s];
}

struct tEdge
{
	int to;
	int next;
}edge[MX<<2];
int head[MX],cnt=0;

inline void add(int from,int to)
{
	edge[++cnt].to=to,edge[cnt].next=head[from];
	head[from]=cnt;
}

int dfn[MX],low[MX];
int idx=0;

int scc[MX],scc_idx=0;

bool in_stack[MX];
std::vector<int> stk;

inline void dfs(int now)
{
	//printf("now: %d\n",now);
	dfn[now]=low[now]=++idx;
	in_stack[now]=1;
	stk.push_back(now);
	for(int i=head[now];i;i=edge[i].next)
	{
		int yt=edge[i].to;
		if(!dfn[yt])
		{
			dfs(yt);
			low[now]=min(low[now],low[yt]);
		}
		else if(in_stack[yt])//只有还在栈的(没有处理的)才更新,不然没用
		{
			low[now]=min(low[now],dfn[yt]);
		}
	}
	if(dfn[now]==low[now])
	{
		scc_idx++;
		int y;
		do
		{
			y=stk.back();
			scc[y]=scc_idx;
			in_stack[y]=0;
			stk.pop_back();
		}while(y!=now);
	}
}

string fq[MX][2];

int main(int argc, char const *argv[])
{
	n=read();
	for(int i=1;i<=n;i++)
	{
		cin>>fq[i][0]>>fq[i][1];
		int x1=_hash(fq[i][0]),x2=_hash(fq[i][1]);
		add(x2,x1);
	}
	m=read();
	for(int i=1;i<=m;i++)
	{
		string s1,s2;
		cin>>s1>>s2;
		int x1=_hash(s1),x2=_hash(s2);
		add(x1,x2);
	}
	for(int i=1;i<=n*2;i++)
	{
		if(!dfn[i]) dfs(i);
	}
	//printf("%d\n",scc_idx);
	for(int i=1;i<=n;i++)//女的抛了个男的,男的找个新的女的,新的女的抛了她的男的,那个男的找了一开始那个女的......\jk
	{
		int x1=_hash(fq[i][0]),x2=_hash(fq[i][1]);
		if(scc[x1]==scc[x2])
		{
			printf("Unsafe\n");
		}
		else
		{
			printf("Safe\n");
		}
	}
	return 0;
}

P2194 HXY烧情侣

直接跑 \(tarjan\) 即可,存下每个 \(scc\) 的元素,排序+乘法原理。

#include<bits/stdc++.h>

using namespace std;

const int N=1*100000+233;
const int M=3*100000+233;

#define LL long long
#define inf 0x3f3f3f3f

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

int n,m;
int w[N];

struct tEdge
{
	int to,next;	
}edge[M];
int head[N],cnt=0;

inline void add(int from,int to)
{
	edge[++cnt].to=to,edge[cnt].next=head[from];
	head[from]=cnt;
}

int dfn[N],low[N],idx=0;

bool in_stack[N];
std::vector<int> stk;

int scc[N],scc_idx=0;
std::vector<int> bk[N];

inline void tarjan(int now)
{
	dfn[now]=low[now]=++idx;
	stk.push_back(now);
	in_stack[now]=1;
	for(int i=head[now];i;i=edge[i].next)
	{
		int yt=edge[i].to;
		if(!dfn[yt])
		{
			tarjan(yt);
			low[now]=min(low[now],low[yt]);
		}
		else if(in_stack[yt])
		{
			low[now]=min(low[now],dfn[yt]);
		}
	}
	if(dfn[now]==low[now])
	{
		int y;
		++scc_idx;
		do
		{
			y=stk.back();
			stk.pop_back();
			in_stack[y]=0;
			scc[y]=scc_idx;
			bk[scc_idx].push_back(w[y]);
		}
		while(y!=now);
	}
}

int main(int argc, char const *argv[])
{
	n=read();
	for(int i=1;i<=n;i++) w[i]=read();
	m=read();
	for(int i=1;i<=m;i++)
	{
		int u,v;
		u=read(),v=read();
		add(u,v);
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i]) tarjan(i);
	}
	int ans=0;
	LL fn=1ll;
	for(int i=1;i<=scc_idx;i++)
	{
		sort(bk[i].begin(),bk[i].end());
		int minn=bk[i][0],num=0;
		ans+=minn;
		for(std::vector<int>::iterator it=bk[i].begin();it!=bk[i].end();it++)
		{
			if((*it)==minn)
			{
				num++;
			}
			else break;
		}
		fn=fn*(LL)num;
	}
	cout<<ans<<" "<<fn<<endl;
	return 0;
}

强连通分量 END

posted @ 2023-08-13 11:30  hewo  阅读(9)  评论(0编辑  收藏  举报