码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2841

时间:2017-06-20 14:46:25      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:简单   ems   head   log   als   分享   div   pac   using   

边双联通分量

具体详解蓝书上十分详细,因为必须是奇数个人坐在一起,那么一个人如果能选上,就必须处在一个简单奇圈中。而奇圈也是一个边双联通分量,所以我们先把边双联通分量都挖出来,然后进行二分图染色。

奇圈不能被二分图染色,所以标记所有不能被染色的点,减去就是答案

技术分享
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, top, cnt, tot, color, ans, m;
int dfn[N], low[N], st[N], vis[N], col[N], mark[N], head[N];
struct edge {
    int nxt, to;
} e[N << 4];
vector<int> G[N];
void link(int u, int v)
{
    e[++cnt].nxt = head[u];
    head[u] = cnt;
    e[cnt].to = v;
}
void tarjan(int u, int last)
{
    dfn[u] = low[u] = ++tot; st[++top] = u;
    for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last)
    {
        if(!dfn[e[i].to])
            tarjan(e[i].to, u);
        if(dfn[e[i].to] != -1)
            low[u] = min(low[u], low[e[i].to]);
    }
    if(low[u] == dfn[u])
    {
        ++color;
        while(st[top + 1] != u)
        {
            dfn[st[top]] = -1;
            col[st[top]] = color;
            --top; 
        }
    }
}
bool dfs(int u, int c)
{
    vis[u] = c;
    for(int i = 0; i < G[u].size(); ++i)
    {
        int v = G[u][i];
        if(vis[v] == c) return false;
        if(!vis[v]) 
            if(!dfs(v, c ^ 1)) 
                return false;
    }
    return true;
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i)
    {
        int u, v; scanf("%d%d", &u, &v);
        link(u, v);
        link(v, u);
    }
    for(int i = 1; i <= n; ++i) 
        if(!dfn[i])
            tarjan(i, 0);
    for(int i = 1; i <= n; ++i)
        for(int j = head[i]; j; j = e[j].nxt)
            if(col[e[j].to] == col[i])
            {
                G[e[j].to].push_back(i);
                G[i].push_back(e[j].to);
            } 
    memset(vis, -1, sizeof(vis));
    for(int i = 1; i <= n; ++i)
        if(vis[i] == -1 && !dfs(i, 0)) 
            mark[col[i]] = 1;
    ans = n;
    for(int i = 1; i <= n; ++i)
        if(mark[col[i]])
            --ans;
    printf("%d\n", ans);
    return 0;
}
View Code

 

bzoj2841

标签:简单   ems   head   log   als   分享   div   pac   using   

原文地址:http://www.cnblogs.com/19992147orz/p/7053812.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!