• CF962F Solution


    题目链接

    题解

    本题需要求出所有简单环所覆盖的边。可以发现所有简单环均为点双联通分量,因此可以求出所有点双连通分量,判断它们是否为环。求点双连通分量可以用tarjan,而环的边数一定等于点数。但是本题需要输出边,而一般tarjan中所求为点双中的点,因为一个点可以同时属于多个点双,使得找出点后反推边变得十分麻烦(题解作者写挂了QAQ),但以边来推点却较为简单。因此直接在栈中记录点双中的边,每当发现一个点双,统计其点数与边数,如果相等则将其中的边加入答案序列即可。Tips:需要用\(vis\)数组记录每条双向边是否已经入栈过,否则点双最后的返祖边会被重复进栈(因为第一次找点双时其并不在遍历过程中真的经过)。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10,M=2100010;
    int fst[N],nxt[2*M],v[2*M],id[2*M],cnt=1;
    int dfn[N],low[N],num;
    int st[N],top,ans[N],tot;
    bool vis[N];
    set<int> qwq,qaq;//qwq:当前点双中的点,qaq:当前点双中的边
    set<int>::iterator it;
    void add(int x,int y,int z)
    {
    	v[++cnt]=y,id[cnt]=z;
    	nxt[cnt]=fst[x],fst[x]=cnt;
    }
    void tarj(int x)
    {
    	dfn[x]=low[x]=++num;
    	for(int i=fst[x];i;i=nxt[i])
    	{
    		int y=v[i];
    		if(vis[id[i]]) continue;
    		st[++top]=i; vis[id[i]]=1; 
    		if(!dfn[y])
    		{
    			tarj(y);
    			low[x]=min(low[x],low[y]);
    			if(low[y]>=dfn[x])
    			{
    				qwq.clear(),qaq.clear();
    				qwq.insert(x);
    				int pos=0;
    				while(pos!=i) 
    				{
    					pos=st[top--];
    					qwq.insert(v[pos]);
    					qaq.insert(id[pos]);
    				}
    				if(qaq.size()==qwq.size())
    					for(it=qaq.begin();it!=qaq.end();it++) ans[++tot]=*it;
    			}
    		}
    		else low[x]=min(low[x],dfn[y]);
    	}
    }
    int main()
    {
    	int n,m,x,y;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		add(x,y,i),add(y,x,i);	
    	}
    	for(int i=1;i<=n;i++)
    		if(!dfn[i]) {num=0; tarj(i);}
    	printf("%d\n",tot);
    	sort(ans+1,ans+tot+1);
    	for(int i=1;i<=tot;i++) printf("%d ",ans[i]); 
    	return 0;
    }
    
  • 相关阅读:
    难道真的是RedBook错了?
    用一个土办法证明RedBook的错误
    Md5 Loader Demo
    simple shadow mapping
    又遇到让人疑惑的问题
    [洛谷P1037][题解]产生数
    [洛谷P1279][题解]字串距离
    [洛谷P1122][题解]最大子树和
    [洛谷P1144][题解]最短路计数
    Vue 之 Data
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14508384.html
Copyright © 2020-2023  润新知