题意:判断有多少个强连通分量是由两个完全图连接一条边形成的图。
思路:tarjan算法进行判断割边,如果只有一条割边在分别对两部分判断是否为完全图,如果有3条割边且有4个点,判断是否为一条链即可。
#include <iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<map>
#include<stdlib.h>
#include<time.h>
using namespace std;
typedef long long ll;
const int N=110;
struct data
{
int to,next;
} tu[N*N];
int head[N],low[N],dfn[N];
int ip;
int step;
void init()
{
ip=0;
step=1;///遍历的步数
memset(head,-1,sizeof(head));
memset(dfn, 0, sizeof(dfn));
}
void add(int u,int v)
{
tu[ip].to=v,tu[ip].next=head[u],head[u]=ip++;
}
int ff,d1,d2,num;
void tarjan(int u,int pre)
{
dfn[u] = low[u] = step++;
num++;
for(int i = head[u]; i!=-1 ; i=tu[i].next)
{
int to = tu[i].to;
if(!dfn[to])
{
tarjan(to,u);
low[u]=min(low[u],low[to]);
if(low[to]>dfn[u])
ff++,d1=u,d2=to;///printf("%d--%d\n",u,to);///表示一条割边
}
else if(to!=pre)
low[u]=min(low[u],dfn[to]);
}
}
vector<int>v1,v2;
bool vis[110];
void dfs1(int u,int pre)
{
v1.push_back(u);
vis[u]=1;
for(int i=head[u]; i!=-1; i=tu[i].next)
if(tu[i].to!=pre&&!vis[tu[i].to])
dfs1(tu[i].to,u);
}
void dfs2(int u,int pre)
{
v2.push_back(u);
vis[u]=1;
for(int i=head[u]; i!=-1; i=tu[i].next)
if(tu[i].to!=pre&&!vis[tu[i].to])
dfs2(tu[i].to,u);
}
int rd[110];
int dfs3(int u,int pre)
{
if(rd[u]==3)
return 0;
for(int i=head[u]; i!=-1; i=tu[i].next)
if(tu[i].to!=pre&&!vis[tu[i].to])
{
int t=dfs3(tu[i].to,u);
if(!t)return 0;
}
return 1;
}
int main()
{
int t,o=1;
scanf("%d",&t);
while(t--)
{
init();
memset(rd,0,sizeof(rd));
memset(vis,0,sizeof(vis));
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
rd[a]++;
rd[b]++;
}
int ans=0;
for(int i=1; i<=n; i++)
if(!dfn[i])
{
ff=0;
num=0;
tarjan(i,-1);
if(ff==1)
{
// cout<<d1<<"-->"<<d2<<endl;
dfs1(d1,d2);
dfs2(d2,d1);
int l1=v1.size(),l2=v2.size();
if(l1==l2)
{
int flag=1;
for(int i=1; i<l1; i++)
if(rd[v1[i]]!=l1-1)
{
flag=0;
break;
}
if(rd[v1[0]]!=l1)
flag=0;
if(flag)
{
for(int i=1; i<l2; i++)
if(rd[v2[i]]!=l2-1)
{
flag=0;
break;
}
if(rd[v2[0]]!=l2)
flag=0;
if(flag)
ans++;
}
}
v1.clear();
v2.clear();
}
else if(ff==3&&num==4)
{
if(dfs3(i,-1))
ans++;
}
}
printf("Case #%d: %d\n",o++,ans);
}
return 0;
}