【综合图论】PKU-2942-Knights of the Round Table

本文深入解析了一道复杂的图论题目,运用了补图、双连通分量和二分图等多个概念。通过Tarjan算法寻找连通分支,并利用深度优先搜索进行染色,最终确定不在奇圈中的顶点数量。
部署运行你感兴趣的模型镜像

综合性很强的一道图论题,用到了补图,双连通分量,二分图等几个知识点,这里有某位大牛的神解题报告点击打开链接

题目

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
#define N 1005
vector<int> vec[N],lin[N];
stack<int> sta;
int n,step,cnt,ans,low[N],dfn[N],ins[N],col[N];
bool p[N][N];
void tarjan(int now,int pre)
{
    low[now]=dfn[now]=step++;
    sta.push(now);
    ins[now]=1;
    int len=vec[now].size();
    for(int i=0;i<len;i++)
    {
        int u=vec[now][i];
        if(u==pre)continue;
        if(dfn[u]==-1)
        {
            tarjan(u,now);
            low[now]=min(low[now],low[u]);
            if(low[u]>=dfn[now])
            {
                while(1)
                {
                    int x=sta.top();
                    sta.pop();
                    ins[x]=0;
                    lin[cnt].push_back(x);
                    if(u==x)break;
                }
                lin[cnt++].push_back(now);
            }
        }
        else
        {
            if(ins[u])low[now]=min(low[now],dfn[u]);
        }
    }
}
void dfs(int id,int u,int c)
{
    col[u]=c;
    int len=lin[id].size();
    for(int i=0;i<len;i++)
    {
        int x=lin[id][i];
        if(u==x||col[x]!=-1)continue;
        if(!p[u][x])dfs(id,x,c^1);            //找相邻的点染与当前点不同的色
    }
}
void slove()
{
    cnt=step=0;
    while(!sta.empty())sta.pop();
    memset(ins,0,sizeof(ins));
    memset(dfn,-1,sizeof(dfn));
    for(int i=0;i<n;i++)            //tarjan算法求连通分支
    {
        if(dfn[i]!=-1)continue;
        tarjan(i,-1);
    }
    bool ok[N];
    memset(ok,false,sizeof(ok));
    for(int i=0;i<cnt;i++)
    {
        memset(col,-1,sizeof(col));
        dfs(i,lin[i][0],0);            //染色
        int len=lin[i].size();
        bool flag=false;
        for(int j=0;j<len;j++)
        {
            for(int k=0;k<len;k++)
            {
                int x=lin[i][j];
                int y=lin[i][k];
                if(x!=y&&!p[x][y]&&col[x]==col[y])            //判断是否是二分图,如果x和y相邻并且他们同色就说明这个连通分支不是二分图
                {
                    flag=true;
                    break;
                }
            }
            if(flag)break;
        }
        if(flag)
        {
            for(int j=0;j<len;j++)ok[lin[i][j]]=true;            //不是二分图既是奇圈,里面的点都符合要求
        }
    }
    ans=0;
    for(int i=0;i<n;i++)
    {
        if(!ok[i])ans++;            //找出不在奇圈的点数
    }
}
int main()
{
    //freopen("a.txt","r",stdin);
    int m;
    while(scanf("%d%d",&n,&m)&&n+m)
    {
        memset(p,false,sizeof(p));
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            x--,y--;
            p[x][y]=p[y][x]=true;
        }
        for(int i=0;i<n;i++)
        {
            vec[i].clear();
            lin[i].clear();
        }
        for(int i=0;i<n;i++)            //取补图
        {
            for(int j=0;j<n;j++)
            {
                if(p[i][j]&&i!=j)continue;
                vec[i].push_back(j);
            }
        }
        slove();
        printf("%d\n",ans);
    }
    return 0;
}


您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

PKU - Reid(北大 - 鹏城实验室行人重识别数据集)可能可以通过以下途径查找相关资源: ### 官方渠道 一般来说,数据集的创建团队可能会在其官方网站或者学术平台上发布该数据集以及相关的说明文档、示例代码等。可以尝试搜索北京大学、鹏城实验室的官方网站,看是否有关于 PKU - Reid 数据集的介绍与下载链接。 ### 学术资源平台 - **IEEE Xplore**:该平台收录了大量计算机视觉领域的学术论文和研究成果,可能会有使用 PKU - Reid 数据集进行研究的论文,在这些论文中往往会提及数据集的获取方式以及一些使用该数据集的方法和结果。 - **ACM Digital Library**:同样是一个权威的学术资源平台,有很多关于计算机视觉、模式识别等领域的研究,也许能找到 PKU - Reid 相关的资源。 - **arXiv**:这是一个预印本平台,很多研究人员会在上面发布自己的最新研究成果,可能会有 PKU - Reid 数据集的相关研究和资源。 ### 代码托管平台 - **GitHub**:许多研究人员会将自己使用数据集进行实验的代码开源在 GitHub 上。可以在 GitHub 上搜索“PKU - Reid”,可能会找到一些基于该数据集的代码实现、数据处理脚本等。 以下是一个简单的示例,假设在 GitHub 上找到了处理 PKU - Reid 数据集的 Python 脚本: ```python # 示例代码仅为示意,非真实可用代码 import os # 假设这是读取 PKU - Reid 数据集图像的函数 def read_pku_reid_images(data_dir): image_files = [] for root, dirs, files in os.walk(data_dir): for file in files: if file.endswith('.jpg') or file.endswith('.png'): image_files.append(os.path.join(root, file)) return image_files # 使用示例 data_directory = 'path/to/pku_reid_dataset' images = read_pku_reid_images(data_directory) print(f"Found {len(images)} images in the PKU - Reid dataset.") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值