bzoj 1718: [Usaco2006 Jan] Redundant Paths 分离的路径【tarjan】

首先来分析一下,这是一张无向图,要求没有两条路联通的点对个数
有两条路连通,无向图,也就是说,问题转化为不在一个点双连通分量里的点对个数
tarjan即可,和求scc还不太一样……

#include<iostream>
#include<cstdio>
using namespace std;
const int N=5005;
int n,m,h[N],cnt=1,x,y,dfn[N],low[N],tmp,s[N],top,bl[N],col,d[N],ans;
bool v[N];
struct qwe
{
    int ne,no,to;
}e[20005];
int read()
{
	int r=0,f=1;
	char p=getchar();
	while(p>'9'||p<'0')
	{
		if(p=='-')
			f=-1;
		p=getchar();
	}
	while(p>='0'&&p<='9')
	{
		r=r*10+p-48;
		p=getchar();
	}
	return r*f;
}
void add(int u,int v)
{
 	cnt++;
    e[cnt].ne=h[u];
    e[cnt].no=u;
    e[cnt].to=v;
    h[u]=cnt;
}
void tarjan(int u)
{
    dfn[u]=low[u]=++tmp;
    s[++top]=u;
    for(int i=h[u];i;i=e[i].ne)
		if(!v[i])
		{
			v[i]=v[i^1]=1;
			if(dfn[e[i].to])
				low[u]=min(low[u],dfn[e[i].to]);
			else
			{
				tarjan(e[i].to);
				low[u]=min(low[u],low[e[i].to]);
			}
		}
    if(!bl[u])
    {
        ++col;
        while(low[u]<=dfn[s[top]])
			bl[s[top--]]=col;
    }
}
int main()
{
    n=read(),m=read();
    while(m--)
    {
        int x=read(),y=read();
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++)
		if(!dfn[i])
			tarjan(i);
    for(int i=1;i<=cnt;i++)
		if(bl[e[i].no]!=bl[e[i].to])
			d[bl[e[i].no]]++,d[bl[e[i].to]]++;
    for(int i=1;i<=col;i++)
		if(d[i]==2)
			ans++;
    printf("%d",(ans+1)/2);
    return 0;
}
posted @ 2018-05-09 14:40  lokiii  阅读(130)  评论(0编辑  收藏  举报