新年的毒瘤

虽然一看就知道是用tarjan求割点的,诶诶诶但我还是得去翻了翻题解。

发现哇好妙啊,被删掉的点一定不是割点,因为删掉的话图就不连通了,但是一棵树是连通的。 

现在还是没有编完的。

我们要找的点就是从不是割点的点里面找到边数为m-(n-2)的点 ,这真的非常显然啊,我为什么这么蠢呢

还没有处理边数,mark一下,中午回来继续打。

----------------------------------------------------------------------分割线

硬是中午不让我睡觉,明明前面已经差不多了,就是WA了两个点 

真TM想骂人啊,其实static那个地方是不能乱用的,之前的标记就是根节点的位置那里打错了

一直发现输出少了一个点,就是说标记多大了一个点,就是我的children是用static,那么意味着只要有一个或多个儿子节点,根节点的children就不会为一,然后我们就给根节点打上了标记,噢然后就调了1.5h+真酸爽啊我想睡午觉

#include<cstdio>

#include<cstring>

#include<algorithm>
#include<cstdlib>
using namespace std;
#define maxn 1000007
#define min(x,y) x<y?x:y
int fa[maxn],visit[maxn],mark[maxn],low[maxn],dfn[maxn],num[maxn];
int pre[maxn],to[maxn],next[maxn];
int tip=0;
inline void clear()
{
memset(fa,0,sizeof(int));
memset(pre,0,sizeof(int));
memset(to,0,sizeof(int));
memset(next,0,sizeof(int));
memset(visit,0,sizeof(int));
memset(mark,0,sizeof(int));
memset(num,0,sizeof(int));
inline void addedge(int x,int y)
{
next[++tip]=pre[x]; pre[x]=tip; to[tip]=y; num[x]++;
}
void dfs(int now)
{
static int counter=0;
int p=pre[now],children=0;
dfn[now]=low[now]=++counter;
visit[now]=1;
while(p)
{
if(!visit[to[p]])
{
fa[to[p]]=now;
children++;
dfs(to[p]);
low[now]=min(low[now],low[to[p]]);
if(!fa[now]&&children>1)mark[now]=1;
if(fa[now]&&dfn[now]<=low[to[p]])mark[now]=1;
}
else if(to[p]!=fa[now])
low[now]=min(low[now],dfn[to[p]]);
p=next[p];
}
return;
}
int main()
{
clear();
int n,m,temp1,temp2,c=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&temp1,&temp2);
if(temp1==temp2)continue;
addedge(temp1,temp2);
addedge(temp2,temp1);
}
dfs(1);
for(int i=1;i<=n;i++)
if(!mark[i]&&num[i]==m-(n-2))c++;
printf("%d\n",c);
for(int i=1;i<=n;i++)
if(!mark[i]&&num[i]==m-(n-2))printf("%d ",i);
return 0;
}

转载于:https://www.cnblogs.com/OcahIBye/p/6732424.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值