Body Building(求割边)

来源:互联网 发布:stc15单片机最小系统图 编辑:程序博客网 时间:2024/06/03 18:19



题意:判断有多少个强连通分量是由两个完全图连接一条边形成的图。

思路: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;}


0 0
原创粉丝点击