https://www.luogu.org/blog/cjyyb/solution-p3225
思路还是比较好理解的,不过实现起来挺复杂。。。
虽然数据水 但还是注意初始化别搞错了。。我的Cut数组初始化为0时sizeof写的是cut,看了半天没找出来。。。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#define ll long long
using namespace std;
const int maxn=610;
int dfn[maxn],low[maxn],color[maxn];
bool Cut[maxn];
ll head[maxn],nnext[maxn*4],to[maxn*4];
int tot;
ll num,cut,id,n,m,rs,root,ans1,ans2,group,Case;
void add(ll x,ll y)
{
tot++;
nnext[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void ycl()
{
memset(Cut,0,sizeof(Cut));
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(color,0,sizeof(color));
ans1=group=n=tot=id=0;
ans2=1;
}
void tarjan(int x,int fa)
{
dfn[x]=low[x]=++id;
for(int i=head[x];i;i=nnext[i])
{
int y=to[i];
if(dfn[y]==0)
{
tarjan(y,x);
if(y==fa) continue;
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
if(x!=root) Cut[x]=true;
else rs++;
}
}
else
{
low[x]=min(low[x],low[y]);
}
}
}
void dfs(int x)
{
color[x]=group;
num++;
for(int i=head[x];i;i=nnext[i])
{
int y=to[i];
if(Cut[y]&&color[y]!=group)
{
cut++;
color[y]=group;
}
if(!color[y]) dfs(y);
}
}
int main()
{
Case=1;
ll x,y;
while(cin>>m&&m)
{
ycl();
for(int i=1;i<=m;i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
n=max(n,x);
n=max(n,y);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
root=i;
rs=0;
tarjan(i,i);
if(rs>=2) Cut[i]=true;
}
}
for(int i=1;i<=n;i++)
{
if(!color[i]&&!Cut[i])
{
++group;
num=cut=0;
dfs(i);
if(cut==0)
{
ans1+=2;
ans2*=(num-1)*num/2;
}
if(cut==1)
{
ans1+=1;
ans2*=num;
}
if(cut>=2)
{
;
}
}
}
cout<<"Case "<<Case++<<": "<<ans1<<" "<<ans2<<endl;
}
return 0;
}