新年的毒瘤

虽然一看就知道是用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;
}
posted @ 2017-04-19 11:17  OcahIBye  阅读(242)  评论(0编辑  收藏  举报