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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章