2017上海市高校程序设计邀请赛_E

problem list
E 章鱼哥没有女朋友

这里写图片描述

  • 仔细分析发现项链如果只是一个单纯的环 n==m
  • 如果项链某个珠子生成树,增加的边的条数和珠子数是一样的,即 n==m
  • 这里是要求只有一个环,但是一般的是判定是否有环而不是数总共的环数,所以这里换种思路,就是说强连通分量只有一个,用tarjan解决
  • 所以最后要求
  • n >=3
  • n == m
  • 只有一个强连通分量
  • 无重边和自环

#include <bits/stdc++.h>
using namespace std;
typedef long long           LL ;
typedef unsigned long long ULL ;
const int    maxn = 100000 + 10;
const int    inf  = 0x3f3f3f3f ;
const int    npos = -1         ;
const double eps  = 1e-20      ;

struct GRAPH{
    int n, m;
    int ui[maxn], vi[maxn], fi[maxn], ne[maxn], ct;
    struct node{
        int index;
        int lowlink;
        int onstack;
    };
    node vtx[maxn];
    int idx, top, ct1;
    int group[maxn], belong[maxn], stack[maxn];
    void Init(int x, int y){
        n=x, m=y, ct=0;
        memset(fi,-1,sizeof(fi));
    }
    void Add_Edge(int x, int y){
        ui[ct]=x;
        vi[ct]=y;
        ne[ct]=fi[x];
        fi[x]=ct++;
    }
    void Tarjan_Init(void){
        idx=0, ct1=0, top=0;
        memset(vtx,0,sizeof(vtx));
        memset(group,0,sizeof(group));
        memset(belong,0,sizeof(belong));
    }
    void Tarjan(int u){
        ++idx;
        vtx[u].index=idx;
        vtx[u].lowlink=idx;
        vtx[u].onstack=1;
        stack[top++]=u;
        int v;
        for(int k=fi[u];k!=-1;k=ne[k]){
            v=vi[k];
            if(!vtx[v].index){
                Tarjan(v);
                vtx[u].lowlink=min(vtx[u].lowlink,vtx[v].lowlink);
            }else if(vtx[v].onstack){
                vtx[u].lowlink=min(vtx[u].lowlink,vtx[v].index);
            }
        }
        if(vtx[u].index==vtx[u].lowlink){
            ct1++;
            do{
                v=stack[--top];
                vtx[v].onstack=0;
                belong[v]=ct1;
                group[ct1]++;
            }while(v!=u);
        }
    }
    int Tarjan_Driver(void){
        Tarjan_Init();
        for(int i=1;i<=n;i++)
            if(!vtx[i].index)
                Tarjan(i);
        return ct1;
    }
};
GRAPH G;
int n, m, ans, u, v;
int a[200][200];
int main(){
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    while(~scanf("%d %d",&n,&m)){
        ans=!(n<3 || n!=m);
        G.Init(n,m);
        memset(a,0,sizeof(a));
        for(int i=0;i<m;i++){
            scanf("%d %d",&u,&v);
            if(ans){
                if(a[u][v] || u==v){
                    ans=0;
                }else{
                    G.Add_Edge(u,v);
                    G.Add_Edge(v,u);
                }
                a[u][v]=1;
            }
        }
        if(ans){
            ans=(1==G.Tarjan_Driver());
        }
        puts(ans?"Bingo":"Break up");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值