poj 2942 LA3523 点-双…
2013-12-14 20:02
232 查看
这个题目的意思是:有一些骑士 , 需要开圆桌会议 , 但有一些骑士不能坐在一起 , 问最少有多少个骑士不能参加任何一个会议
。
注意: 不是开一次会议 , 而是开很多次会议 , 每次会议至少3个人 ,
问有哪些骑士是任何一次都不能参加的 , 一个骑士可以参加多个会议。
这是一个无向点-双连通子图的问题 , 先把所有Bcc都求出来 , 然后判断那些bcc中的骑士超过3个人 , 并且人数奇数 , 对于判断
, 可以用判断一个图存不存在奇环 , 对于奇环 ,
我们用交叉染色搜索奇圈的方法来判断当前双连通分量中是否存在奇圈 , 如果双连通分量中存在奇圈 ,
那么我们就能确定 , 这个双连通分量中的所有骑士都能被安排坐下 , 因为如果这个双连通分量有偶数骑士 , 并且存在一个奇圈 ,
那么我们确定肯定存在其他奇圈 , 如果这个双连通分量有奇数个骑士, 那么肯定存在一个环包含这个双连通分量中的所有骑士。
代码:
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010 ;
int pre[MAXN] , iscut[MAXN] , bccno[MAXN] , dfs_clock ,
bcc_cnt;
int n , m;
int A[MAXN][MAXN] ;
int color[MAXN] ;
vectorgrap[MAXN] , bcc[MAXN];
stacks , t;
int dfs(int u ,int fu)
{
int lowu =
pre[u] = ++dfs_clock;
int child =
0;
for(int i =
0 ; i < grap[u].size() ; i++)
{
int v =
grap[u][i];
if(!pre[v])
{
s.push(u);
t.push(v);
child +=
1;
int lowv =
dfs(v , u);
if(lowu
> lowv) lowu = lowv;
if(lowv
>= pre[u])
{
iscut[u] =
true ;
bcc_cnt++;
bcc[bcc_cnt].clear(); // 清空
for(;
;)
{
int x =
s.top() , y = t.top();
s.pop() ;
t.pop();
if(bccno[x]
!= bcc_cnt) {bcc[bcc_cnt].push_back(x) ; bccno[x]
= bcc_cnt;}
if(bccno[y]
!= bcc_cnt) {bcc[bcc_cnt].push_back(y) ; bccno[y]
= bcc_cnt;}
if(x == u
&& y ==
v) break;
}
}
}
。
注意: 不是开一次会议 , 而是开很多次会议 , 每次会议至少3个人 ,
问有哪些骑士是任何一次都不能参加的 , 一个骑士可以参加多个会议。
这是一个无向点-双连通子图的问题 , 先把所有Bcc都求出来 , 然后判断那些bcc中的骑士超过3个人 , 并且人数奇数 , 对于判断
, 可以用判断一个图存不存在奇环 , 对于奇环 ,
我们用交叉染色搜索奇圈的方法来判断当前双连通分量中是否存在奇圈 , 如果双连通分量中存在奇圈 ,
那么我们就能确定 , 这个双连通分量中的所有骑士都能被安排坐下 , 因为如果这个双连通分量有偶数骑士 , 并且存在一个奇圈 ,
那么我们确定肯定存在其他奇圈 , 如果这个双连通分量有奇数个骑士, 那么肯定存在一个环包含这个双连通分量中的所有骑士。
代码:
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010 ;
int pre[MAXN] , iscut[MAXN] , bccno[MAXN] , dfs_clock ,
bcc_cnt;
int n , m;
int A[MAXN][MAXN] ;
int color[MAXN] ;
vectorgrap[MAXN] , bcc[MAXN];
stacks , t;
int dfs(int u ,int fu)
{
int lowu =
pre[u] = ++dfs_clock;
int child =
0;
for(int i =
0 ; i < grap[u].size() ; i++)
{
int v =
grap[u][i];
if(!pre[v])
{
s.push(u);
t.push(v);
child +=
1;
int lowv =
dfs(v , u);
if(lowu
> lowv) lowu = lowv;
if(lowv
>= pre[u])
{
iscut[u] =
true ;
bcc_cnt++;
bcc[bcc_cnt].clear(); // 清空
for(;
;)
{
int x =
s.top() , y = t.top();
s.pop() ;
t.pop();
if(bccno[x]
!= bcc_cnt) {bcc[bcc_cnt].push_back(x) ; bccno[x]
= bcc_cnt;}
if(bccno[y]
!= bcc_cnt) {bcc[bcc_cnt].push_back(y) ; bccno[y]
= bcc_cnt;}
if(x == u
&& y ==
v) break;
}
}
}
相关文章推荐
- uva 10047
- STL中优先队列的用法
- 并查集及其路径的压缩
- 求欧拉回路的路径 dfs的一种新运用
- poj 2676
- poj 2531
- poj 2251
- poj 2488
- 网络流 SAP优化算法 (…
- 网络流之Dinic算法
- 基于增广路的网络流算法
- poj 1789 最小生成树
- poj 1469
- poj 3041二分匹配
- scanf和cin的区别 (效率的差距)
- 匈牙利算法
- poj 1062 最短路
- poj 1860 最短路
- poj 3259 最短路(带负环)
- poj 3080