题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件: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(双联通分量,交叉染色判二分图)的更多相关文章

  1. lightoj 1300 边双联通分量+交叉染色求奇圈

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...

  2. POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】

    LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...

  3. 训练指南 UVALive - 3523 (双联通分量 + 二分图染色)

    layout: post title: 训练指南 UVALive - 3523 (双联通分量 + 二分图染色) author: "luowentaoaa" catalog: tru ...

  4. 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

    [POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Su ...

  5. POJ 2942 Knights of the Round Table 补图+tarjan求点双联通分量+二分图染色+debug

    题面还好,就不描述了 重点说题解: 由于仇恨关系不好处理,所以可以搞补图存不仇恨关系, 如果一个桌子上面的人能坐到一起,显然他们满足能构成一个环 所以跑点双联通分量 求点双联通分量我用的是向栈中pus ...

  6. 【POJ2942】Knights of the Round Table(二分图 点双联通分量)

    题目链接 大意 给定\(N\)个点与\(M\)个关系,每个关系表示某两个点间没有直接的边相连,求不在所有奇环上的点的个数. (\(1\le N\le 1e3,1\le M\le 1e6\)) 思路 考 ...

  7. Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定

    题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...

  8. 【洛谷 SP2878】Knights of the Round Table(双联通分量)

    先放这吧,没时间写,明天再补 "明天到了" 题目链接 题意:求不在任何奇环内的点的数量. Tarjan求点双联通分量,然后再染色判断是不是二分图就好了. 只是不懂为什么Tarjan ...

  9. 『Tarjan算法 无向图的双联通分量』

    无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...

随机推荐

  1. 7. leetcode 104. Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  2. C#使用Xamarin开发可移植移动应用(1.入门与Xamarin.Forms页面),附源码

    前言 什么是Xamarin? Xamarin始创于2011年,旨在使移动开发变得难以置信地迅捷和简单. Xamarin的产品简化了针对多种平台的应用开发,包括iOS.Android.Windows P ...

  3. NYOJ--353--bfs+优先队列--3D dungeon

    /* Name: NYOJ--3533D dungeon Author: shen_渊 Date: 15/04/17 15:10 Description: bfs()+优先队列,队列也能做,需要开一个 ...

  4. H5滚动轮播插件

      概述 JRedu 随着前端技术的发展,越来越多的H5技术被应用到实际开发中,尤其是js插件更是无处不用,本章节我们主要分享下如何去自己封装一个滚动轮播插件. 1效果图如下: 2主要功能   支持超 ...

  5. bootstrap&NPM淘宝代理镜像

    box-shadow 属性向框添加一个或多个阴影. < box-shadow: h-shadow v-shadow blur spread color inset; h-shadow必需.水平阴 ...

  6. Linux - 简明Shell编程13 - 用户输入(UserInput)

    脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 1 - arguments #!/bin/bash i ...

  7. 关于 Overtrue 的拼音库 overtrue/pinyin 为何 travis 为 error【社交系统研发日记十】

    什么是ThinkSNS ? ThinkSNS(简称TS),一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+(简称TS+).社交系统 ...

  8. C语言 进程控制---创建进程fork()函数

    #include "sys/types.h" #include "stdio.h" #include "stdlib.h" #include ...

  9. 基于tgp协议的套接字的 粘包解决

    客户端 import socket import struct import json phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM ...

  10. SpringMVC基础-@RequestMapping

    @RequestMapping @RequestMapping是一个用来处理请求地址映射的注解 可用于类或方法上.   类定义处:提供初步的请求映射信息.相当于当前 WEB 应用的根目录   方法处: ...