• poj 2942 Knights of the Round Table(点双连通分量+奇圈判定)


    链接:https://vjudge.net/problem/POJ-2942 

    题意:给定一个无向图,求出补图,然后求补图中有多少个点不属于任何奇圈。

    分析:首先是骑士有不能坐在一起的人,不好想,反过来想,相当于和其他人可以坐在一起,连一条边,围成一圈就变成了该点是否在某个点双连通分量里,所以先用Tarjan算法处理出所有的点双连通分量。然后还有一个要求,该点得在某个含奇数个点的点双连通分量里。

    首先点双连通分量有两个性质:1.如果该分量里有一个奇圈,那么其他所有点也必然在某个奇圈中;2.含有一个奇圈的充要条件是该分量不是二分图。

    - - 知道了这些性质就好做点了。。处理完点双连通分量以后,对每个分量都用染色法判断是否是二分图,如果是二分图,那么这些人不能坐在一起开会,否则每个点都标记一下,等处理完所有分量后统计下没被标记的点数,就是答案。注意当分量中只有两个点时,虽然是二分图,但是也不满足条件。

    是道好题。。但wa了9发才过。。主要是Tarjan的模板出错了没找到。。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<stack>
      5 #include<vector>
      6 #include<set>
      7 using namespace std;
      8 const int maxn=1005;
      9 int dfn[maxn],low[maxn],fa[maxn],cnt=0,bcc_cnt=0;
     10 int n,m;
     11 bool vis[maxn],Is_cut[maxn];
     12 struct Edge{
     13     int u,v;
     14     Edge(int _u,int _v):u(_u),v(_v){}
     15 };
     16 vector<Edge> edges;
     17 vector<int>G[maxn];
     18 set<int>bcc[maxn];
     19 int g[maxn][maxn];
     20 stack<int>sta;
     21 void AddEdge(int u,int v){
     22     edges.push_back(Edge(u,v));
     23     edges.push_back(Edge(v,u));
     24     G[u].push_back(edges.size()-2);
     25     G[v].push_back(edges.size()-1);
     26 }
     27 void dfs(int u){
     28     if(vis[u])return ;
     29     vis[u]=true;
     30     dfn[u]=cnt++;
     31     low[u]=dfn[u];
     32     int child=0;
     33     for(int i=0;i<G[u].size();i++){
     34         int v=edges[G[u][i]].v;
     35         if(!vis[v]){
     36             sta.push(G[u][i]);
     37             fa[v]=u;
     38             child++;
     39             dfs(v);
     40             low[u]=min(low[u],low[v]);
     41             if(low[v]>=dfn[u]){
     42                 Is_cut[u]=true;
     43                 bcc[bcc_cnt].clear();
     44                 while(1){
     45                     Edge e=edges[sta.top()];sta.pop();
     46                     bcc[bcc_cnt].insert(e.u);
     47                     bcc[bcc_cnt].insert(e.v);
     48                     if(e.u==u&&e.v==v)break;
     49                 }
     50                 bcc_cnt++;
     51             }
     52         }else if(dfn[v]<dfn[u]&&v!=fa[u]){
     53             sta.push(G[u][i]);
     54             low[u]=min(low[u],dfn[v]);
     55         }
     56     }
     57     if(fa[u]==-1&&child<=1)Is_cut[u]=false;
     58 }
     59 void Tarjan(){
     60     memset(vis,0,sizeof(vis));
     61     memset(Is_cut,0,sizeof(Is_cut));
     62     for(int i=1;i<=n;i++){
     63         if(!vis[i]){
     64             fa[i]=-1;
     65             dfs(i);
     66         }
     67     }
     68 }
     69 
     70 bool ok[maxn];
     71 int color[maxn];
     72 void init(){
     73     edges.clear();
     74     for(int i=1;i<=n;i++)G[i].clear();
     75     cnt=bcc_cnt=0;
     76     while(!sta.empty())sta.pop();
     77     memset(ok,0,sizeof(ok));
     78     for(int i=1;i<=n;i++){
     79         for(int j=1;j<=n;j++)g[i][j]=1;
     80         g[i][i]=0;
     81     }
     82 }
     83 bool Is_btg(set<int> &S){
     84     memset(color,0,sizeof(color));
     85     stack<int> s;
     86     s.push(*S.begin());
     87     color[*S.begin()]=1;
     88     while(!s.empty()){
     89         int u=s.top();s.pop();
     90         for(int i=0;i<G[u].size();i++){
     91             int v=edges[G[u][i]].v;
     92             if(!S.count(v))continue;
     93             if(color[v]==color[u])return false;
     94             if(!color[v]){
     95                 s.push(v);
     96                 color[v]=-color[u];
     97             }
     98         }
     99     }
    100     return true;
    101 }
    102 int main(){
    103 //    freopen("e:\in.txt","r",stdin);
    104     while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){
    105         init();
    106         int u,v;
    107         for(int i=0;i<m;i++){
    108             scanf("%d%d",&u,&v);
    109             g[u][v]=0;g[v][u]=0;
    110         }
    111         for(int i=1;i<=n;i++){
    112             for(int j=i+1;j<=n;j++)
    113                 if(g[i][j])AddEdge(i,j);
    114         }
    115 //        for(int i=1;i<=n;i++){
    116 //            for(int j=0;j<G[i].size();j++){
    117 //                cout<<G[i][j]<<' ';
    118 //            }
    119 //            cout<<endl;
    120 //        }
    121         Tarjan();
    122 //        for(int i=0;i<bcc_cnt;i++){
    123 //            for(set<int>::iterator it=bcc[i].begin();it!=bcc[i].end();it++){
    124 //                cout<<*it<<' ';
    125 //            }
    126 //            cout<<endl;
    127 //        }
    128         for(int i=0;i<bcc_cnt;i++){
    129             int len=bcc[i].size();
    130             if(len>2&&!Is_btg(bcc[i])){
    131                 for(set<int>::iterator it=bcc[i].begin();it!=bcc[i].end();it++)
    132                     ok[*it]=true;
    133             }
    134         }
    135         int ans=0;
    136         for(int i=1;i<=n;i++)
    137             if(!ok[i])ans++;
    138         printf("%d
    ",ans);
    139 
    140     }
    141     return 0;
    142 }
  • 相关阅读:
    安装与配置 Elasticsearch
    推荐几个 WebSocket 服务端实现
    GitLab 修改主机名,更换 IP 配置,配置 SMTP
    Choose GitLab for your next open source project
    大数据全栈式开发语言 – Python
    IPC's epoch 6 is less than the last promised epoch 7
    将/home空间从新挂载到/var/lib/docker
    Initialization failed for Block pool <registering> (Datanode Uuid unassigned) service to IP1:8020 Invalid volume failure config value: 1
    查看端口被那个进程占用
    查看java进程启动的详细参数和过程
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7668619.html
Copyright © 2020-2023  润新知