UVAlive3523_Knights of the Round Table
圆桌骑士。有的骑士之间是相互憎恨的,不能连坐,需要安排奇数个骑士围着桌子坐着,大于3个,求哪些骑士不可能安排到座位。
根据给定的关系,如果两个骑士之间没有憎恨关系,那么连边。最终就是求有多少个点无法位于奇圈之内。
首先求所有联通分量,对于每个连通分量二分图染色,看看是否存在一个奇圈,如果有一个,那么这个联通分量里面的所有点都可以在至少一个奇圈之内。(详细的见白书)
下面重点说说如何找联通分量的。
方法是用一个栈来维护下面走过的边,如果当前点是割点,那么把在这个点后面加入的边全部退出来,把这些点拿出来,就构成了一个独立的联通分量。
这个维护是很有意思的,因为是递归操作,有点难以理解。
结合下面的图来说:

这也就是题目的样例,如图,假设我们现在走1->2->4,现在2是关键点,于是就把2->4这条边出来,(2,4)两个点构成一个分量。
同理的有3,5。
但是问题也许会是,我一开是走的是1->2->3->5,那么会不会导致(2,3,5)构成一个分量,不会的!因为在你处理完3后,3->5这条边就已经被拿出来了,最终也只有(1,2,3)。这个递归和栈的混合运用是有一点难以理解,好好想想就清楚了。
还有一个问题,2-4并不能看成是一个双联通分量,但是在这个题目里面不会对答案产生影响,因为2个点也无法构成奇圈(3个点呢?嘿嘿不会有3个点的情况)。想想就知道了,加油!
召唤代码君:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define maxn 2000100
using namespace std; vector<int> bcc[maxn];
int next[maxn],first[],to[maxn],edge;
int low[],d[],belong[],color[];
int a[][];
int n,m,T=,bccnum,ans,u,v,dfs_clock;
int U[maxn],V[maxn],top;
bool can[]; void _init()
{
T++,ans=dfs_clock=bccnum=top=,edge=-;
for (int i=; i<=n; i++) low[i]=d[i]=belong[i]=first[i]=-,can[i]=false;
} void addedge(int uu,int vv)
{
edge++;
to[edge]=vv,next[edge]=first[uu],first[uu]=edge;
edge++;
to[edge]=uu,next[edge]=first[vv],first[vv]=edge;
} bool find(int cur,int tag)
{
for (int i=first[cur]; i!=-; i=next[i])
{
if (belong[to[i]]!=tag) continue;
if (color[to[i]]==color[cur]) return true;
if (color[to[i]]!=-) continue;
color[to[i]]=-color[cur];
if (find(to[i],tag)) return true;
}
return false;
} void dfs(int cur,int fa)
{
low[cur]=d[cur]=++dfs_clock;
for (int i=first[cur]; i!=-; i=next[i])
{
if ((i^)==fa) continue;
if (d[to[i]]==-)
{
U[++top]=cur,V[top]=to[i];
dfs(to[i],i);
low[cur]=min(low[cur],low[to[i]]);
if (low[to[i]]>=d[cur])
{
bcc[++bccnum].clear();
for (;;top--)
{
if (belong[U[top]]!=bccnum) belong[U[top]]=bccnum,bcc[bccnum].push_back(U[top]);
if (belong[V[top]]!=bccnum) belong[V[top]]=bccnum,bcc[bccnum].push_back(V[top]);
if (U[top]==cur && V[top]==to[i])
{
top--;
break;
}
}
for (unsigned j=; j<bcc[bccnum].size(); j++) color[bcc[bccnum][j]]=-;
color[bcc[bccnum][]]=;
if (find(bcc[bccnum][],bccnum))
for (unsigned j=; j<bcc[bccnum].size(); j++) can[bcc[bccnum][j]]=true;
}
}
else low[cur]=min(low[cur],low[to[i]]);
}
} int main()
{
while (scanf("%d%d",&n,&m) && (n|m))
{
_init();
while (m--)
{
scanf("%d%d",&u,&v);
a[u][v]=a[v][u]=T;
}
for (int i=; i<=n; i++)
for (int j=i+; j<=n; j++)
if (a[i][j]!=T) addedge(i,j);
for (int i=; i<=n; i++)
if (d[i]==-) dfs(i,-);
for (int i=; i<=n; i++) if (!can[i]) ans++;
printf("%d\n",ans);
}
return ;
}
UVAlive3523_Knights of the Round Table的更多相关文章
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- POJ 2942 Knights of the Round Table
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 10911 Acce ...
- poj 2942 Knights of the Round Table 圆桌骑士(双连通分量模板题)
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 9169 Accep ...
- 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
- POJ 2942 Knights of the Round Table - from lanshui_Yang
Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels ...
- UVALive - 3523 - Knights of the Round Table
Problem UVALive - 3523 - Knights of the Round Table Time Limit: 4500 mSec Problem Description Input ...
- POJ 2942Knights of the Round Table(tarjan求点双+二分图染色)
Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 13954 Accepted: 4673 Description Bein ...
- poj 2942 Knights of the Round Table - Tarjan
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
- 【POJ】2942 Knights of the Round Table(双连通分量)
http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...
随机推荐
- Python调用matplotlib实现交互式数据可视化图表案例
交互式的数据可视化图表是 New IT 新技术的一个应用方向,在过去,用户要在网页上查看数据,基本的实现方式就是在页面上显示一个表格出来,的而且确,用表格的方式来展示数据,显示的数据量会比较大,但是, ...
- 更改VS Code界面为简体中文
.先看一下效果(请忽略我的颜色主题): 1. 点击侧边栏的“扩展”按钮,或者按下Ctrl+Shift+X,安装需要的语言包 2. 通过命令面板设置语言 点击“查看”——“命令面板”,或者快捷键Ctr ...
- 执行sh脚本报“/usr/bin/env: "sh\r": 没有那个文件或目录”错误
出现这个错误的原因是出错的语句后面多了“\r”这个字符,换言之,脚本文件格式的问题,我们只需要把格式改成unix即可: vi xx.sh :set ff :set ff=unix :wq!
- canvas反向裁剪技巧
我们都知道在canvas 可以通过clip来实现剪裁功能,其步骤一般是先设置要裁剪的区域(路径),然后通过ctx.clip()的实现裁剪,裁剪之后,后续的绘制只能在裁剪的区域显示效果,比如如下一段代码 ...
- 我是如何将页面加载时间从6S降到2S的?
写在前面 生活在信息爆炸的今天,我们每天不得不面对和过滤海量的信息--无疑是焦躁和浮动的,这就意味着用户对你站点投入的时间可能是及其吝啬的(当然有一些刚需站点除外). 如何给用户提供迅速的响应就显得十 ...
- Redis集群搭建与使用
前端时间开发中需要用到redis缓存数据,考虑到单台redis的不稳定性,后采用redis集群的方式来实现,由于之前没有接触过,过程中也是踩了不少的坑,拖了三天总算是搞定了,最近公司比较闲,总结了一下 ...
- PHP中你应该知道的require()文件包含的正确用法
以前看一些PHP框架源码的时候,很奇怪在文件包含的时候,会用dirname(__FILE__)来拼凑文件路径,不知道这样做有什么好处,后来终于发现了其中的缘由. 我们来看一个简单的例子: 有a,b,c ...
- sprint3(第一天)
1.今天计划了sprint3要做的内容: 整合前台和后台,然后发布让用户使用,然后给我们反馈再进行改进 2.backlog表格: ID Name Est How to demo 1 实现用户登录与权限 ...
- Daily Srum 10.26
Daily Scrum Meeting 虽然TFS的相关使用已经在上面贴出来一段时间,但是要运用TFS还是有些困难的,特别是TFS的代码管理机制,所以我们让部分人先弄清楚,然后再教授给其他人.终于大家 ...
- Daily Scrumming* 2015.10.27(Day 8)
一.总体情况总结 今日项目总结: 前后端同一了API设计以及API权限认证.用户状态保存的开发方案 API以及后端模型已经开始开发,前端UEditor开始学习,本周任务有良好的起步 前后端完成分工,后 ...