题目来源:http://acm.nyist.edu.cn/problem/1663
题目描述:

因为 PK上个月没有去师范看她女朋友,所以PK 的女朋友最近又不理他了。异地恋实在是太辛苦了,理工到师范的距离,对于他来说,就像是驻马店到广州的距离。
曾有诗这样写道:
世上最遥远的距离,不是生与死的距离,不是天各一方,而是我就站在你面前,你却不知道我爱你。
PK决定要送给他的女朋友一条项链,希望能挽回女朋友的心,但他长期打 ACM 已经分辨不出什么是项链了,所以想请你帮帮他。
在眼中,他所买的东西就是个n个点和m条边构成的无向图(……)。判断这个图是不是项链,我们要做以下三件事情:
1.首先我们要在图上找一个环。而且我们要保证在图上只能找到这一个环。
2.环上可以长出一些树,这些树的根都在环上。树应该由至少一个节点组成,但为了美观起见,应该要能找到至少 3 棵树。
3.重边和自环是不允许出现的。不然女孩子有可能不小心把头伸进里面,然后出不来……
换句话说合格的图应该保证只有一个环,可以组成至少3课树,没有重边和自环。
如果满足以上三个条件,PK就会非常高兴,并大叫一声 Bingo。否则,他的女朋友就会和他分手……

输入描述:

第一行,给出 n,m (1 <= n <= 100, 0 <= m <= 10^5)。
接下来 m 行,每一行有两个整数 ui,vi (1 <= ui, vi <= n) 表示 ui 和 vi 之间有边相连。可能存在重边和自环。

输出描述:

如果是项链则输出 Bingo,否则输出 Break up。

样例输入:
6 6
6 3
6 4
5 1
2 5
1 4
5 4

6 5
5 6
4 6
3 1
5 1
1 2
样例输出:
Bingo
Break up

解法1
满足:
1.n==m
2.n>=3
3.没有重边和自环
就是项链
解法2
直接依照题意搜索(待补

/** 6 6 6 3 6 4 5 1 2 5 1 4 5 4 6 5 5 6 4 6 3 1 5 1 1 2 **/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#define ll long long
const int N=1e5+5;
#define inf 0x3f3f3f3f
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
struct node
{
    int n,m,k;
}xl[N];
int ans,sum,n,m,flag;
vector<int> tu[105];
ll a[105][105],b[105],check[105],vis[105];
void dfs(int x){
    for(int i=0;i<tu[x].size();i++){
        if(!vis[tu[x][i]]){
            vis[tu[x][i]]=1;
            check[tu[x][i]]=ans;
            dfs(tu[x][i]);
        }
    }
}
bool dfss(int x,int y){
    if(b[x]==1)
        sum++;
    if(xl[y].n-sum<3)
        return false;
    for(int i=0;i<tu[x].size();i++){
        if(!vis[tu[x][i]]){
            int k=tu[x][i];
            vis[k]=1;
            if(!dfss(k,y))
                return 0;
        }
    }
    return 1;
}
int main(){
    int x,y,i;while (cin>>n>>m) {
        mem(xl, 0);
        mem(a, 0);
        for (i = 1; i <= m; i++) {
            cin >> x >> y;
            if (a[x][y] == 0) {
                tu[x].push_back(y);
                tu[y].push_back(x);
            }
            a[x][y]++;
            a[y][x]++;
            b[x]++;
            b[y]++;
        }
        if (n != m || n < 3) {
            cout << "Break up" << endl;
            return 0;
        }
        vis[xl[i].k] = 1;
        mem(vis, 0);
        mem(check, 0);
        ans = 0;
        for (i = 1; i <= n; i++) {
            if (!vis[i]) {
                vis[i] = 1;
                ans++;
                check[i] = ans;
                dfs(i);
            }
        }
        for (i = 1; i <= n; i++) {
            int k = check[i];
            xl[k].n++;
            for (int j = 1; j <= n; j++) {
                xl[k].m += a[i][j];
            }
            xl[k].k = i;
        }
        flag = 0;
        for (i = 1; i <= ans; i++) {
            if (xl[i].n == xl[i].m / 2 && xl[i].n >= 3) {
                sum = 0;
                memset(vis, 0, sizeof(vis));
                vis[xl[i].k] = 1;
                if (dfss(xl[i].k, i)) {
                    flag++;
                }
            }
        }
        if (flag == 1) {
            cout << "Bingo" << endl;
        } else {
            cout << "Break up" << endl;
        }
    }
    return 0;
}