poj 2942 Knights of the Round Table 点重联通分量

简介:

  书上把这放在边联通的第一道题,于是一开始就按边写了,一直写不对,重新想了一遍,才发现是点联通……


/*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#define pb push_back
using namespace std;
int n,m;
int Map[1005][1005];
vector<int> org[1005];
vector<int> belong[1005];
int vis[1005];
int dph[1005],low[1005];
int d;
int num=0;
bool ok[1005];
stack<int> S;
void dfs(int v,int f)
{
    vis[v]=1;
    dph[v]=low[v]=d++;
    S.push(v);
    for(int i=0; i<org[v].size(); i++)
    {
        int u=org[v][i];
        if(u==f)continue;
        if(vis[u]==1)low[v]=min(low[v],dph[u]);
        else if(!vis[u])
        {
            dfs(u,v);
            low[v]=min(low[v],low[u]);
            if(low[u]>=dph[v])
            {
                num++;
                belong[v].pb(num);
                belong[u].pb(num);
                while(S.top()!=u)// 注意边界,如果吧push放在for循环里就是!=v不用pop,否则就是!=u最后还要pop
                {
                    belong[S.top()].pb(num);
                    S.pop();
                }
                S.pop();
            }
        }
    }
    vis[v]=2;
}
int Tarjan() //搜索重联通分量
{
    num=0;
    while(!S.empty())S.pop();
    for(int i=1; i<=n; i++)
    {
        d=0;
        if(!vis[i])
            dfs(i,-1);
    }
}
int dye(int v,int c,int flag)//1,-1染色
{
    vis[v]=c;
    for(int i=0; i<org[v].size(); i++)
    {
        int &u=org[v][i];
        if(ok[u])
        {
            if(vis[u]==0&&dye(u,-c,flag))return 1;
            if(vis[u]==c)return 1;
        }
    }
    return 0;
}
int use[1005];
int Count()
{
    int ans=0;

    memset(use,0,sizeof(use));
    for(int k=1; k<=num; k++)
    {
        memset(ok,0,sizeof(ok));
        memset(vis,0,sizeof(vis));
        for(int i=1; i<=n; i++)
        {
            if(find(belong[i].begin(),belong[i].end(),k)!=belong[i].end())
                ok[i]=1;
        }
        for(int i=1; i<=n; i++)
        {
            if(ok[i])
            {
                if(dye(i,1,k))
                    for(int j=1; j<=n; j++)
                        use[j]+=ok[j];
                break;
            }
        }
    }
    for(int i=1; i<=n; i++)
        if(!use[i])ans++;
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&m)&&n+m)
    {
        int a,b;
        int i,j;
        memset(vis,0,sizeof(vis));
        memset(Map,0,sizeof(Map));
        for(i=1; i<=n; i++)
        {
            org[i].clear();
            belong[i].clear();
            Map[i][i]=1;
        }
        for(i=0; i<m; i++)
        {
            scanf("%d%d",&a,&b);
            Map[a][b]=Map[b][a]=1;
        }
        for(i=1; i<=n; i++) //建立不憎恨的图
        {
            for(j=i; j<=n; j++)
                if(!Map[i][j])
                {
                    org[i].pb(j);
                    org[j].pb(i);
                }
        }
        Tarjan();
        printf("%d\n",Count());
    }
}


目录
相关文章
|
监控 NoSQL 数据库
云数据库MongoDB监控指标解读与关注
为方便开发者的使用,云数据库MongoDB提供了许多查看其运行状态指标的命令。如何分析这些繁多的数据指标?又如何使用这些数据指标解决我们业务中出现的问题呢?本文将带大家了解查看这些监控指标的命令并为大家逐一解读其中一些重要的指标。
11213 0
|
机器学习/深度学习 编解码 算法
【动手学计算机视觉】第九讲:传统目标检测之DPM模型
DPM模型在我心里的印象一直都非常深刻,不仅是因为它非常经典,此外,它是我进入CV领域看的第一篇文章。还记得当初开始做项目时,老师就发给我一篇文章,并反复声明,要认真研究,好好学习。我反复把这篇文章看了很多遍,也把源码看了几遍,真是深深的被这个神作惊叹到了。真不愧为传统目标识别领域的经典之作,虽然时间过去很多年,特征提取加机器学习这一套在效率上远不如深度学习,但是DPM的影响力和思想依然非常有生命力,从后面深度学习模型中经常可以看到DPM的身影,DPM的原文从2009年至今引用已经超过8000次,它的价值可见一斑,下面就来介绍一下这个经典的目标检测模型。
【动手学计算机视觉】第九讲:传统目标检测之DPM模型
|
11月前
|
存储 缓存 NoSQL
常见的 NoSQL 数据库有哪些?
常见的 NoSQL 数据库有哪些?
666 59
|
12月前
|
数据采集 前端开发 搜索推荐
|
JavaScript 前端开发
js小功能--如何实现按住shift拖拽多选div
js小功能--如何实现按住shift拖拽多选div
233 0
|
定位技术 数据安全/隐私保护
幻兽帕鲁服务器参数配置指南&参数解读&参数推荐
幻兽帕鲁服务器支持非常多的参数配置,本文带来了详细的参数解读、配置教程,以及亲身体验后的参数搭配,大幅增加你的游戏体验!
3053 10
|
Oracle Java 关系型数据库
win11系统下载安装 jdk8安装与环境变量的配置
win11系统下载安装 jdk8安装与环境变量的配置
1035 0
|
存储 网络性能优化 vr&ar
深入理解AMBA总线(十七)AXI是如何提高性能的
深入理解AMBA总线(十七)AXI是如何提高性能的
3082 1