UVALive - 3523 - Knights of the Round Table
Time Limit: 4500 mSec
Problem Description
Input
The input contains several blocks of test cases. Each case begins with a line containing two integers 1 ≤ n ≤ 1000 and 1 ≤ m ≤ 1000000. The number n is the number of knights. The next m lines describe which knight hates which knight. Each of these m lines contains two integers k1 and k2, which means that knight number k1 and knight number k2 hate each other (the numbers k1 and k2 are between 1 and n). The input is terminated by a block with n = m = 0.
Output
Sample Input
Sample Output
2
题解:双连通分量+二分图性质及判断,首先抽象出本题的模型,可以相邻而坐的骑士之间连一条边,对于简单奇环中的每一个骑士都可以参加会议,而不被任意一个简单奇环包含的骑士不能参加会议,因此此题就是统计不在任意一个简单奇环中的节点个数,做出这个题首先需要知道两个知识点
一、二分图中必定没有奇环
二、点双连通分量是满足如下性质:任意两条边都在同一个简单环中
通常来说如果要求任意两条边在同一个简单环中,那么就是求点-双连通,因此此题就相当于求完点双连通之后判断一下每个双连通分量是否是二分图,其实还需要证明一个东西就是如果该双连通分量不是二分图,那么其中每一个节点都会存在于某个奇环内,证明很简单不赘述。有了这些理论基础之后其实就是两个模板放在一起即可。
#include <bits/stdc++.h> using namespace std; #define REP(i, n) for (int i = 1; i <= (n); i++)
#define sqr(x) ((x) * (x)) const int maxn = + ;
const int maxm = + ;
const int maxs = + ; typedef long long LL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd; const LL unit = 1LL;
const int INF = 0x3f3f3f3f;
const LL mod = ;
const double eps = 1e-;
const double inf = 1e15;
const double pi = acos(-1.0); struct Edge
{
int u, v;
}; int gra[maxn][maxn];
int n, m;
int dfs_clock, bcc_cnt, bccno[maxn], pre[maxn], is_cut[maxn];
int color[maxn], odd[maxn];
vector<int> G[maxn], bcc[maxn]; stack<Edge> S; int dfs(int u, int fa)
{
int lowu = pre[u] = ++dfs_clock;
int child = ;
for (auto v : G[u])
{
Edge e = (Edge){u, v};
if (!pre[v])
{
S.push(e);
child++;
int lowv = dfs(v, u);
lowu = min(lowu, lowv);
if (lowv >= pre[u])
{
is_cut[u] = ;
bcc_cnt++;
bcc[bcc_cnt].clear();
for (;;)
{
Edge x = S.top();
S.pop();
if (bccno[x.u] != bcc_cnt)
{
bcc[bcc_cnt].push_back(x.u);
bccno[x.u] = bcc_cnt;
}
if (bccno[x.v] != bcc_cnt)
{
bcc[bcc_cnt].push_back(x.v);
bccno[x.v] = bcc_cnt;
}
if (x.u == u && x.v == v)
{
break;
}
}
}
}
else if (pre[v] < pre[u] && v != fa)
{
S.push(e);
lowu = min(lowu, pre[v]);
}
}
if (fa < && child == )
is_cut[u] = ;
return lowu;
} void find_bcc()
{
memset(pre, , sizeof(pre));
memset(is_cut, , sizeof(is_cut));
memset(bccno, , sizeof(bccno));
dfs_clock = bcc_cnt = ;
for (int i = ; i < n; i++)
{
if (!pre[i])
{
dfs(i, -);
}
}
} bool bipartite(int u, int cnt)
{
for (auto v : G[u])
{
if (bccno[v] != cnt)
continue;
if (color[v] == color[u])
{
return false;
}
if (!color[v])
{
color[v] = - color[u];
if (!bipartite(v, cnt))
{
return false;
}
}
}
return true;
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while (cin >> n >> m && (n || m))
{
for (int i = ; i < n; i++)
{
bcc[i].clear();
G[i].clear();
}
memset(gra, , sizeof(gra));
int u, v;
for (int i = ; i < m; i++)
{
cin >> u >> v;
u--, v--;
gra[u][v] = gra[v][u] = ;
}
for (int i = ; i < n; i++)
{
for (int j = i + ; j < n; j++)
{
if (!gra[i][j])
{
G[i].push_back(j);
G[j].push_back(i);
}
}
}
find_bcc();
memset(odd, , sizeof(odd));
for (int i = ; i <= bcc_cnt; i++)
{
for (auto v : bcc[i])
{
bccno[v] = i;
}
memset(color, , sizeof(color));
int u = bcc[i][];
color[u] = ;
if (!bipartite(u, i))
{
for (auto v : bcc[i])
{
odd[v] = ;
}
}
}
int ans = n;
for (int i = ; i < n; i++)
{
if (odd[i])
ans--;
}
cout << ans << endl;
}
return ;
}
UVALive - 3523 - Knights of the Round Table的更多相关文章
- uvalive 3523 Knights of the Round Table 圆桌骑士(强连通+二分图)
题目真心分析不出来.看了白书才明白,不过有点绕脑. 容易想到,把题目给的不相邻的关系,利用矩阵,反过来建图.既然是全部可行的关系,那么就应该能画出含奇数个点的环.求环即是求双连通分量:找出所有的双连通 ...
- UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
由于互相憎恨的骑士不能相邻,把可以相邻的骑士连上无向边,会议要求是奇数,问题就是求不在任意一个简单奇圈上的结点个数. 如果不是二分图,一定存在一个奇圈,同一个双连通分量中其它点一定可以加入奇圈.很明显 ...
- UVALive 3523 : Knights of the Round Table (二分图+BCC)
题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; ; int n,m; int dfn[maxn],low[ ...
- uva 3523 Knights of the Round Table
题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议. 白书算法指南 对于每个双联通分量,若不是二分图,就把里面的节点标记 #include ...
- 【LA3523】 Knights of the Round Table (点双连通分量+染色问题?)
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...
- 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 ...
- 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 ...
随机推荐
- [MXNet逐梦之旅]练习一·使用MXNet拟合直线手动实现
[MXNet逐梦之旅]练习一·使用MXNet拟合直线手动实现 code #%% from matplotlib import pyplot as plt from mxnet import autog ...
- Asp.Net Core 程序部署到Linux(centos)生产环境(一):普通部署
运行环境 照例,先亮底 centos:7.2 cpu:1核 2G内存 1M带宽 辅助工具:xshell xftp 搭建.net core运行环境 .net core 的运行环境我单独写了一篇,请看我的 ...
- 【c#】RabbitMQ学习文档(六)RPC(远程调用)
远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...
- 使用ajax+php+mysql实现数据库定时刷新
php版本5.5.9,mysql版本5.7. 所以php链接mysql就是使用mysql_connect. 如果遇到了连接时没有成功也没有失败的情况时,就重启mysql,或重启docker(睡一觉就好 ...
- 阿里云ACE共创空间——MQ消息队列产品测试
一.产品背景消息队列是阿里巴巴集团自主研发的专业消息中间件. 产品基于高可用分布式集群技术,提供消息订阅和发布.消息轨迹查询.定时(延时)消息.资源统计.监控报警等一系列消息云服务,是企业级互联网架构 ...
- javascript基础修炼(4)——UMD规范的代码推演
javascript基础修炼(4)--UMD规范的代码推演 1. UMD规范 地址:https://github.com/umdjs/umd UMD规范,就是所有规范里长得最丑的那个,没有之一!!!它 ...
- VisualStudio移动开发(C#、VB.NET)Smobiler开发平台——AlbumView相册控件的使用方式
AlbumView控件 一. 样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的“Smobiler Components”拖动一个AlbumView控件到窗体界面上 修改 ...
- Java开发笔记(十一)常见的数学函数
前面介绍了Java编程的四则运算,虽然提供了基础的加减乘除符号,但是数学上还有其它运算符号,包括四舍五入用到的约等号≍.求绝对值的“| |”.开平方的“√ ̄”,这些运算符形态各异,而且并非ASCII码 ...
- 解决: 移动端经mouseover显示出的弹层中链接点击问题
通常我们会遇到这样的需求,导航菜单在鼠标划过的时候显示自定义弹层,在弹层中有一些链接需要点击后跳转或者其他一些事件.比如: $(".menu li").on("mouse ...
- 【20190405】JavaScript-整理一些常用正则式
匹配中文字符: let reg=/([\u4E00-\u9FFF]+)/; //\u代表Unicode编码 匹配电话号码: let reg=/^1[34578]\d{9}$/; 给每三位数字添加一个逗 ...