zoukankan      html  css  js  c++  java
  • POJ 2942 Knights of the Round Table(双连通分量)

    http://poj.org/problem?id=2942

    题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置。如果意见发生分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防止赞同和反对的票一样多,知道哪些骑士相互憎恨之后,你的任务是统计有多少个骑士不可能参加任何一个会议。

    思路 :这个题牵扯的知识点挺多的,具体的可以参考白书上解释的蛮详细的。

    #include <iostream>
    #include <stdio.h>
    #include <stack>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    const int maxn = 1100 ;
    
    struct Edge
    {
        int u,v ;
        Edge(int u ,int v):u(u),v(v) {}
    } ;
    
    int pre[maxn],dfs_clock ,iscut[maxn],Bcc_cnt,Bccno[maxn] ;
    vector<int>G[maxn],Bcc[maxn] ;
    stack<Edge>S ;
    int odd[maxn],color[maxn] ;
    int A[maxn][maxn] ;
    
    int dfs(int u,int fa)
    {
        int lowu = pre[u] = ++dfs_clock ;
        int child = 0 ;
        for(int i = 0 ; i < G[u].size() ; i++)
        {
            int v = G[u][i] ;
            Edge e = (Edge)
            {
                u,v
            } ;
            if(!pre[v])
            {
                S.push(e) ;
                child++ ;
                int lowv = dfs(v,u) ;
                lowu = min(lowu,lowv) ;
                if(lowv >= pre[u])
                {
                    iscut[u] = true ;
                    Bcc_cnt++ ;
                    Bcc[Bcc_cnt].clear() ;
                    for( ; ; )
                    {
                        Edge x = S.top() ;
                        S.pop() ;
                        if(Bccno[x.u] != Bcc_cnt)
                        {
                            Bcc[Bcc_cnt].push_back(x.u) ;
                            Bccno[x.u] = Bcc_cnt ;
                        }
                        if(Bccno[x.v] != Bcc_cnt)
                        {
                            Bcc[Bcc_cnt].push_back(x.v) ;
                            Bccno[x.v] = Bcc_cnt ;
                        }
                        if(x.u == u && x.v == v) break ;
                    }
                }
            }
            else if(pre[v] < pre[u] && v != fa)
            {
                S.push(e) ;
                lowu = min(lowu,pre[v]) ;
            }
        }
        if(fa < 0 && child == 1)
            iscut[u] = 0 ;
        return lowu ;
    }
    
    void find_Bcc(int n)
    {
        memset(pre,0,sizeof(pre)) ;
        memset(iscut,0,sizeof(iscut)) ;
        memset(Bccno,0,sizeof(Bccno)) ;
        dfs_clock = Bcc_cnt = 0 ;
        for(int i = 0 ; i < n ; i++)
            if(!pre[i])
                dfs(i,-1) ;
    }
    
    bool bipartite(int u,int b)
    {
        for(int i = 0 ; i < G[u].size() ; i++)
        {
            int v = G[u][i] ;
            if(Bccno[v] != b)
                continue ;
            if(color[v] == color[u]) return false ;
            if(!color[v])
            {
                color[v] = 3-color[u] ;
                if(!bipartite(v,b))
                    return false ;
            }
        }
        return true ;
    }
    
    int main()
    {
        int kase = 0,n,m ;
        while(scanf("%d %d",&n,&m) == 2 && n)
        {
            for(int i = 0 ; i < n ; i++ )
                G[i].clear() ;
            memset(A,0,sizeof(A)) ;
            for(int i = 0 ; i < m ; i++)
            {
                int u,v ;
                scanf("%d %d",&u,&v) ;
                u-- ;
                v-- ;
                A[u][v] = A[v][u] = 1 ;
            }
            for(int u = 0 ; u < n ; u++)
            {
                for(int v = u+1 ; v < n ; v++)
                    if(!A[u][v])
                    {
                        G[u].push_back(v);
                        G[v].push_back(u) ;
                    }
            }
            find_Bcc(n) ;
            memset(odd,0,sizeof(odd)) ;
            for(int i = 1 ; i <= Bcc_cnt ; i++)
            {
                memset(color,0,sizeof(color)) ;
                for(int j = 0 ; j < Bcc[i].size() ; j++)
                    Bccno[Bcc[i][j]] = i ;
                int u = Bcc[i][0] ;
                color[u] = 1 ;
                if(!bipartite(u,i))
                    for(int j = 0 ; j < Bcc[i].size() ; j++)
                        odd[Bcc[i][j]] = 1 ;
            }
            int ans = n ;
            for(int i = 0 ; i < n ; i++)
                if(odd[i]) ans-- ;
            printf("%d
    ",ans) ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    删除MFC单文档默认菜单栏的两种方法
    mfc更改背景色
    (转)VC单选按钮控件(Radio Button)用法
    转:MFC 基于对话的程序界面显示完全后立即执行一个函数
    转:vc6以上如何给MFC对话框添加OnInitDialog函数
    常用网址
    2010年春季学期C语言程序设计答疑安排
    rdlc导出Excel
    SQL Server查询表的结构
    C# WinForm开发系列 WebBrowser
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3543205.html
Copyright © 2011-2022 走看看