poj2942(双联通分量,交叉染色判二分图)
题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1。2.总人数为奇数。3.有仇恨的骑士不能挨着坐。问有几个骑士不能和任何人形成任何的圆圈。
思路:首先反向建立补图,然后问题转换成在图中找奇圈,圈肯定出现在双联通分量中,则求出图的双联通分量,又通过特性知道,一个双联通分量有奇圈则其中的点都可以出现在一个奇圈中。而对于奇圈的判定可以用交叉染色判断是非为二分图,二分图中肯定无奇圈,这里用tarjan算法得出割边(先将点入队),确定双联通分量的根节点,(对于队列中的点)然后进行染色判定,最后标记odd[]代表需要删除的点。
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 1004
#define MAXM 1001000 int n,m,tot,count,top;
int first[MAXN],DFN[MAXN],Low[MAXN],vis[MAXN],col[MAXN],mark[MAXN],stack[MAXM],odd[MAXN];
int G[MAXN][MAXN];
struct Edge
{
int st,to,next,vis;
}edge[2*MAXM];
void addedge(int a,int b)
{
edge[tot].to=b;
edge[tot].st=a;
edge[tot].next=first[a];
edge[tot].vis=0;
first[a]=tot++;
}
int find(int s)
{
for(int i=first[s];i!=-1;i=edge[i].next)
{
int t=edge[i].to;
if(mark[t])
{
if(col[t]==-1)
{
col[t]=!col[s];
return find(t);
}
else if(col[t]==col[s]) return 1;
}
}
return 0;
}
void color(int s)
{
int i;
memset(mark,0,sizeof(mark));
do{
i=stack[top--];
mark[edge[i].st]=1;
mark[edge[i].to]=1;
}while(edge[i].st!=s);
memset(col,-1,sizeof(col));
col[s]=0;
if(find(s))
{
for(int i=1;i<=n;i++)
{
if(mark[i])
odd[i]=1;
}
}
}
void dfs(int s)
{
DFN[s]=Low[s]=++count;
for(int i=first[s];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].vis)continue;
edge[i].vis=edge[i^1].vis=1;
stack[++top]=i;
if(!DFN[v])
{
dfs(v);
Low[s]=min(Low[s],Low[v]);
if(Low[v]>=DFN[s])color(s);
}
else
{
Low[s]=min(Low[s],DFN[v]);
}
}
}
int main()
{
while(scanf("%d%d",&n,&m),n||m)
{
memset(G,0,sizeof(G));
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
G[a][b]=1;
G[b][a]=1;
}
tot=0;
memset(first,-1,sizeof(first));
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(G[i][j]==0)
{
addedge(i,j);
addedge(j,i);
}
}
}
memset(DFN,0,sizeof(DFN));
memset(odd,0,sizeof(odd));
count=0;top=0;
for(int i=1;i<=n;i++)
{
if(!DFN[i])
dfs(i);
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(!odd[i])
ans++;
}
printf("%d\n",ans);
}
return 0;
}
poj2942(双联通分量,交叉染色判二分图)的更多相关文章
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
- POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】
LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...
- 训练指南 UVALive - 3523 (双联通分量 + 二分图染色)
layout: post title: 训练指南 UVALive - 3523 (双联通分量 + 二分图染色) author: "luowentaoaa" catalog: tru ...
- 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)
[POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS Memory Limit: 65536K Total Su ...
- POJ 2942 Knights of the Round Table 补图+tarjan求点双联通分量+二分图染色+debug
题面还好,就不描述了 重点说题解: 由于仇恨关系不好处理,所以可以搞补图存不仇恨关系, 如果一个桌子上面的人能坐到一起,显然他们满足能构成一个环 所以跑点双联通分量 求点双联通分量我用的是向栈中pus ...
- 【POJ2942】Knights of the Round Table(二分图 点双联通分量)
题目链接 大意 给定\(N\)个点与\(M\)个关系,每个关系表示某两个点间没有直接的边相连,求不在所有奇环上的点的个数. (\(1\le N\le 1e3,1\le M\le 1e6\)) 思路 考 ...
- Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定
题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...
- 【洛谷 SP2878】Knights of the Round Table(双联通分量)
先放这吧,没时间写,明天再补 "明天到了" 题目链接 题意:求不在任何奇环内的点的数量. Tarjan求点双联通分量,然后再染色判断是不是二分图就好了. 只是不懂为什么Tarjan ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
随机推荐
- hdu 6045 Is Derek lying?(思维推导)
Problem Description Derek and Alfia are good friends.Derek is Chinese,and Alfia is Austrian.This sum ...
- python实战第一天-socket模块练习
操作系统 Ubuntu 15.10 IDE & editor JetBrains PyCharm 5.0.2 ipython3 Python版本 python-3.4.3 导入socket模块 ...
- mysql忘记密码,修改密码重新安装的一些问题
前言 想要装cobra,却意外发现mysql连接失败,命令行连一下发现无论怎么样都连不上了. 我能想到的密码都用上了,糟糕!看来只能修改密码,或者重装了. 最后是重装搞定的,当然也发现了正确的修改密码 ...
- java中使用poi导出excel表格数据并且可以手动修改导出路径
在我们开发项目中,很多时候会提出这样的需求:将前端的某某数据以excel表格导出,今天就给大家写一个简单的模板. 这里我们选择使用poi导出excel: 第一步:导入需要的jar包到 lib 文件夹下
- mysql创建定时任务,每月1号删除上月数据
1.创建存储过程: CREATE DEFINER=`gzy`@`%` PROCEDURE `delLastMonth`() BEGIN DECLARE lastmonth int; SET lastm ...
- CSS学习笔记!
一.关于图像RGB值和像素值的确定! 腾讯QQ截图软件Ctrl+Alt+A进入截图界面,鼠标变成彩色,便会拾取鼠标当前颜色,再按住Ctrl切换到十六进制格式#******.图像的像素值也在截取框内显示 ...
- django开发者模式中的autoreload是怎样实现的
在开发django应用的过程中,使用开发者模式启动服务是特别方便的一件事,只需要 python manage.py runserver 就可以运行服务,并且提供了非常人性化的autoreload机制, ...
- ubuntu14.04安装ssh和ftp
1.安装SSH >1.先使用netstat -tl或service ssh status查看ssh服务是否开启,如果没有开启,用service ssh restart开启,如果没有安装,使用su ...
- android学习笔记之GridView的使用
除了listview会使用适配器外,还有一种就是GridView,listview是单列多行的显示形式,适用于多项目的查看.而GridView是多行多列的显示形式,一般用在查看图片样式的activit ...
- MATLAB批量读入图片
%% import pictures, and save into images{img_num} function [images, img_num, vertical_border] = impo ...