题目大意:给定n个骑士以及m个讨厌关系,让你找到满足以下关系的需要减去骑士的最少数:

1、每个骑士的两边必须是自己的朋友!

2、每个桌子上必须坐奇数个人,这就意味着必须转化为一个奇圈,如果一个骑士不能和其它骑士组成一个奇圈则除去,并且一个人则也除去,因为一个人不能坐一个桌子!

解题思路:

首先需要知道几个定理:

如果一个强连通分量上存在一个奇圈,则这个连通分量上的任意一个点都在奇圈中!

一个图是二分图当且仅当该图中不存在奇圈!

所以这道题需要先找出强连通分量,然后在强连通分量中找看是否存在奇圈,总人数减去可以组成奇圈的骑士的人数就是需要减去的骑士的人数!

首先对于强连通分量的求法:首先求出割点,首先求出割点: 给每个顶点定义一个low值, low(u)表示从u出发, 经过一条其后代组成的路
径和后向边, 所能到达的最小深度的顶点的编号(如果这个编号大于等于u的编号, 就说明它的后代无法到达比u深度更浅的顶点, 即无法到达u的祖先, 那么u就是个关节点, 具体做法是在DFS每次回溯后拿刚才扩展节点的low与当前节点的dfn比较, 若low>=dfn则当前节点是割点).

low(u)=min{dfn(u), min{low(w)|w是u的儿子}, min{dfn(w)|(u,w) 是一条后向边}}dfn(u)是深搜过程中对顶点的编号值.

在求割点的同时就可以通过一个全局的栈求出点的双连通分量, 具体做法是在DFS每次由当前顶点u深入下一顶点v时, 就将边uv进栈, 若在函数返回后判断出v是割点, 则出栈, 直到uv出栈, 刚才出栈的这些边就属于同一个点双连通分量.

对于点的强连通分量可以通过判断其是否是二分图来决定其是否存在奇圈,如果一个图中有偶数个点,存在一个奇圈,那么这个图的剩余的点就一定也可以组成一个奇圈!

然后就是根据这些题做的啊!

几乎是看别人的代码然后写的结果还是WA了一晚上啊!后来改对了但是还是不了解,看来以后要多多留意这方面的东西了,提供一个大牛的解析地址啊:http://www.answeror.com/?s=2942

下面是代码哈!

#include<iostream>
#include<cstdio>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
using namespace std;
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#define fab(a) (a)>0?(a):0-(a)
#define arc(a) (a)*(a)
#define inf 10000000   //最大值的
#define exp 0.0000001     //浮点型的
#define N    1100 //记录开的数组
bool vis[N],sign[N];
int flag[N];
int map[N][N];
int pre[N];
typedef struct fun
{int x,pre;
}rr;
fun a[N*N*2];
int Stack[N];
int sum,tot,len;
int dfn[N],low[N];
int n,m;
int p[N];
void add(int i, int j)
{a[m].x=j;a[m].pre=pre[i];pre[i]=m++;
}int find(int i,int s)
{int j; p[i]=s;for(j=pre[i]; j!=0; j=a[j].pre){int y=a[j].x;if(vis[y]==false)//不在这次找奇圈的范围内continue;if(p[y]==p[i])//找到奇圈的return 1;if(p[y]==0){if(s==1)find(y,2);elsefind(y,1);}}return 0;
}
void judge(int t)
{ int i;memset(vis,0,sizeof(vis));for(i=0; i<t; i++)vis[flag[i]]=true;for(i=0; i<t; i++){memset(p,0,sizeof(p));if(find(flag[i],1))break;}if(i<t){for(i=0; i<t; i++)if(sign[flag[i]]==false){sign[flag[i]]=true;sum++;}}return ;
}
void dfs(int x, int y)
{int j; dfn[x]=low[x]=tot++;//Stack[len++]=x;int i;for(i=pre[x];i!=0; i=a[i].pre){int s=a[i].x;//代表边的另一个节点的if(s==y)//不能对一个点进行来回的continue;if(!dfn[s])//没有在栈中{dfs(s,x);low[x]=min(low[x],low[s]);if(low[s]>=dfn[x])//就是代表x是割点{flag[0]=x; int t=1;//   for(j=1; Stack[len]!=s;flag[j++]=Stack[--len]);/*      for(j=len-1; Stack[j]!=x; j--){flag[t++]=Stack[j];len--;}*/for(j=len; Stack[j]!=s; ){flag[t++]=Stack[--j];len--;}judge(t);//对flag前面的t个元素进行判断是否为奇圈的 }}elselow[x]=min(low[x],low[s]);}
}
int main()
{while(scanf("%d%d",&n,&m)){if(n==0 && m==0)break;  memset(sign,0,sizeof(sign));memset(pre,0,sizeof(pre));memset(dfn,0,sizeof(dfn));int i,j;for(i=1; i<=n; i++)for(j=1; j<=n; j++)map[i][j]=1;int s,t;while(m--){scanf("%d%d",&s,&t);map[s][t]=map[t][s]=0;}m=0;for(i=1; i<=n; i++)for(j=1+i; j<=n; j++)if(map[i][j]){add(i,j);add(j,i);}sum=0;tot=1;//代表的是对没个点的计数的len=1;//代表的是栈的长度的for(i=1; i<=n; i++)if(!dfn[i])//没有在栈中dfs(i,-1);//对其进行神搜处理的printf("%d\n",n-sum);}return 0;
}

poj2942 圆桌骑士相关推荐

  1. poj2942 圆桌骑士(点双连通分量+二分图染色法判奇环)

    题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 分析:图论 ...

  2. 【图的连通性】poj2942圆桌骑士

    题目描述:有n个骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 这是 ...

  3. POJ2942 UVA1364 Knights of the Round Table 圆桌骑士

    POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则 ...

  4. 圆桌骑士 图的连通性

    题目描述 圆桌骑士是一个非常吸引人的职业.因此,在最近几年里,亚瑟王史无前例的扩招圆桌骑士,并不令人惊讶.现在这里有许多圆桌骑士,每个圆桌骑士都收到一份珍贵的邀请函,被邀请去英灵殿圆桌.这些骑士将要环 ...

  5. 强连通分量 圆桌骑士

    题目描述 圆桌骑士是一个非常吸引人的职业.因此,在最近几年里,亚瑟王史无前例的扩招圆桌骑士,并不令人惊讶.现在这里有许多圆桌骑士,每个圆桌骑士都收到一份珍贵的邀请函,被邀请去英灵殿圆桌.这些骑士将要环 ...

  6. POJ 2942 圆桌骑士 (点双学习笔记)

    割点 在无向连通图G上进行如下定义: • 割点:若删掉某点P后,G分裂为两个或两个以上的子图,则称P为G的割点. • 割点集合:在无向连通图G中,如果有一个顶点集合,删除这个顶点集合以及与该点集中 的 ...

  7. 以圆桌骑士为例浅尝HTML5游戏开发

    随着XHTML的逐渐式微,Chrome,Safari,FireFox,Opera等现代浏览器正在积极完善HTML5实现,IE9也加入到标准的行列并将在今年上半年发布正式版,HTML5时代来临了. 在各 ...

  8. 网页中在线玩圆桌骑士

    演示一个在网页中在线玩街机游戏圆桌骑士的代码: http://www.return8090.com

  9. JS版圆桌骑士DEMO

    同学们,我参加了IE9开发大赛,作品是网页版圆桌骑士,喜欢的话帮忙投票吧! [url=http://ie9.onlinevoc.cn/contest/PercodPage.aspx?ID=43]htt ...

最新文章

  1. C#实现路由器断开连接,更改公网ip
  2. linux红帽网页中文乱码解决,【linux学习笔记】安装redhat时中文显示乱码(小方框)解决方法...
  3. BugKu:cookies 欺骗
  4. dbscan算法_DBSCAN聚类算法探索
  5. Redis成神之路电子版教程已问世,面试题+笔记+项目实战
  6. MongoDB 数据恢复与导出
  7. setuptools find_packages
  8. 交出20分钟后就得到面试通知的一份答卷
  9. 八段锦是一种不错的养生运动
  10. 用友ERP-NC系统 NCFindWeb接口文件读取
  11. julia语言 python解释器_深入Python解释器源码,我终于搞明白了字符串驻留的原理...
  12. 身份证前6位对应的省市区代码(超详细)
  13. PHP手机网店管理系统
  14. win7触摸板怎么关闭_win7系统如何禁用触摸板功能 win7禁用触摸板功能方法【详解】...
  15. python3中26个英文字母排序_26个英文字母的排序是怎样排的?
  16. Android简单制作自定义圆形头像
  17. 尽管凭借主持人的身份成名,张绍刚先生在内心深处却对这一角色认可度很低
  18. ASP.NET MVC Liu_Cabbage 个人博客
  19. 读hdfs上的文件时出现Unable to write to output stream问题的解决方案
  20. 2021-03-13 java八大基本数据类型

热门文章

  1. 【实战】Windows 10 CodeSoft 6 条形码标签打印开发实战 【产品标签设计印刷】【Codesoft】
  2. 数学史资料:中世纪数学
  3. springBoot集成swagger访问报404
  4. 中高级JAVA工程师-面试题汇总
  5. linux运维工程师 倒班,运维人员值班制度
  6. 家用计算机是什么时候开始流行,什么时候电脑在我国开始普及?
  7. 数据可视化(七):可视化设计实战
  8. E-PUCK机器人-例子
  9. 【奇奇怪怪的bug系列】微信小程序
  10. 【Google论文】The Google File System 译文