首页 > 其他分享 >LightOJ - 1300 Odd Personality(边双连通+奇圈判定)

LightOJ - 1300 Odd Personality(边双连通+奇圈判定)

时间:2023-04-07 11:32:54浏览次数:43  
标签:pre cnt 1300 边双 int LightOJ bcc ++ color


题目大意:给出一张无向图,要求找出符合条件的点
条件如下:从该点出发,经过一定数量的边,又回到该点,经过的边不能重复经过,且经过的边的数量为奇数

解题思路:要回到原点,且不能重复经过边,只能在边双连通分量中找了
接着要判断的是有多少个点,只要边双连通分量中有奇圈,那么这个连通分量中的所有点都是符合条件的
所以现在的问题变成了如和判断奇圈了,判断奇圈的话,用二分图染色即可

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
const int M = 20010;

struct Edge{
    int u, v, next;
    Edge() {}
    Edge(int u, int v, int next): u(u), v(v), next(next) {}
}E[M * 2];

int head[N], pre[N], lowlink[N], bccno[N], Stack[N], color[N], num[N];
int tot, n, m, bcc_cnt, dfs_clock, top, cas = 1;
bool vis[N];

void AddEdge(int u, int v) {
    E[tot] = Edge(u, v, head[u]);
    head[u] = tot++;
    E[tot] = Edge(v, u, head[v]);
    head[v] = tot++;
}

void init() {
    memset(head, -1, sizeof(head));
    tot = 0;

    scanf("%d%d", &n, &m);
    int u, v;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        AddEdge(u, v);
    }
}

void dfs(int u, int fa) {
    pre[u] = lowlink[u] = ++dfs_clock;
    Stack[++top] = u;

    for (int i = head[u]; ~i; i = E[i].next) {
        int v = E[i].v;
        if (!pre[v]) {
            dfs(v, u);
            lowlink[u] = min(lowlink[v], lowlink[u]);
            if (lowlink[v] > pre[u]) {
                int x;
                bcc_cnt++;
                num[bcc_cnt] = 0;
                while (1) {
                    x = Stack[top--];
                    bccno[x] = bcc_cnt;
                    num[bcc_cnt]++;
                    if (x == v) break;
                }
            }
        }
        else if (v != fa && pre[v] < pre[u]) lowlink[u] = min(pre[v], lowlink[u]);
    }
}

bool Bit(int u, int No) {
    for (int i = head[u]; ~i; i = E[i].next) {
        int v = E[i].v;
        if (bccno[v] != No) continue;
        if (color[v] == color[u]) return false;
        else if (color[v] + color[u] == 3) continue;
        else {
            color[v] = 3 - color[u];
            if (!Bit(v, No)) return false;
        }
    }
    return true;
}

void solve() {
    memset(pre, 0, sizeof(pre));
    memset(bccno, 0, sizeof(bccno));
    dfs_clock = top = bcc_cnt = 0;

    for (int i = 0; i < n; i++) {
        if (!pre[i]) dfs(i, -1);
        if (top != 0) {
            bcc_cnt++;
            num[bcc_cnt] = 0;
            int x;
            while (top) {
                x = Stack[top--];
                bccno[x] = bcc_cnt;
                num[bcc_cnt]++;
            }
        }
    }

    memset(vis, 0, sizeof(vis));
    memset(color, 0, sizeof(color));

    int ans = 0;
    for (int i = 0; i < n; i++) {

        int u = bccno[i];
        if (vis[u]) continue;
        vis[u] = true;
        color[i] = 1;
        if (!Bit(i, u)) ans += num[u];
    }
    printf("Case %d: %d\n", cas++, ans);
}


int main() {
    int test;
    scanf("%d", &test);
    while (test--) {
        init();
        solve();
    }
    return 0;
}


标签:pre,cnt,1300,边双,int,LightOJ,bcc,++,color
From: https://blog.51cto.com/u_10970600/6175963

相关文章

  • LightOJ - 1400 Employment(婚姻稳定问题)
    题目大意:在一个party上,有N个男的,N个女的,要求你将其配对,使其满足1.男生u和女生v还没配对2.他们喜欢对方的程度都大于喜欢各自当前舞伴的程度如果出现了2的情况,他们就会抛下当前的舞伴,另外组成一对解题思路:这题的话,就是婚姻稳定问题,他的解决方法是,男士不断的求婚,而女士不断的拒......
  • LightOJ - 1063 Ant Hills(割点)
    题目大意:求无向图中,有多少个割点解题思路:模版题了#include<cstdio>#include<cstring>#include<vector>#include<stack>usingnamespacestd;#definemax(a,b)((a)>(b)?(a):(b))#definemin(a,b)((a)<(b)?(a):(b))constintMAXNODE=10005;constintM......
  • LightOJ - 1041 Road Construction(最小生成树)
    题目大意:给你N条边,看能否形成最小生成树,如果存在,输出值,不存在,另外输出解题思路:模版题#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<string>#include<iostream>usingnamespacestd;constintMAXNOD......
  • 启动vagrant up 报错 `await_response_state': scp: /tmp/vagrant-network-entry-eth1
      解决办法Linux df命令用于显示目前在Linux系统上的文件系统的磁盘使用情况统计。Linuxdu命令用于显示目录或文件的大小。du会显示指定的目录或文件所占用的磁盘......
  • CF628B 1300
    题意解析末尾2位是4的倍数即可。每次特判最后一位。代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=3e5+10;strings;b......
  • CF870C 1300*
    题意q次询问1e5,每次给你一个正整数n<=1e9,求最多能分成几个合数解析4是合数,一个想法就是尽量地分4。如果n%40的话说明恰好分完,万事大吉,如果n%4=2的话,6是第二小的合数,可以......
  • C. Maximum Set[数学] [*1300-*1500]
    C.MaximumSet[数学][*1300-*1500]题目链接点我题意:一个集合是漂亮的,如果他的每一个元素都是集合中其他元素的倍数或者因子给定你一个\(l\)和\(r\)让你找出在\(......
  • CF665C 1300 *
    题意给定一个字符串t(t的长度<2*10^5)。每次可以将t中的任一字符改为另一字符(a~z),要求在最短的操作后,t任意两个相邻的字符互不相等。可能有多个答案,请输出任意一种。解析......
  • 点&边双连通分量
    双连通分量参考博客:https://www.cnblogs.com/jiamian/p/11202189.html#_2概念双连通分量有点双连通分量和边双连通分量两种。若一个无向图中的去掉任意一个节点(一条边)都......
  • CF653B 1300
    题意长度为n的字符串(字符串中只有abcdef共6种字母),有q种压缩方式,可以将字符串的前两个字符压成1个字符,求凭借这q种压缩方式,有几种长度为n的字符串最终能被压缩成字符'a'.......