UVALive 6907 Body Building tarjan
Body Building
题目连接:
Description
Bowo is fed up with his body shape. He has a tall posture, but he’s very skinny. No matter how much
he eats, he never gains any weight. Even though he is a computer geek (and he loves it), he wants
a pretty and non-geek girlfriend. Unfortunately, most girls in his surrounding do not like skinny and
unattractive guy. Therefore, Bowo has decided to gain some muscles in his body; he joined a fitness
club and begun to do some body building exercises.
There are a lot of exercise equipments in a fitness club, and usually there should be weightlifting
equipments such as barbell and dumbbell (barbell with shorter rod). Upon seeing a dumbbell, Bowo
cannot help but imagining graphs which are similar to a dumbbell. A graph — which later referred as
“connected component” — of N nodes is called a dumbbell if it fulfills all the following conditions:
(i) All nodes in the graph can be partitioned into two disjoint sets P and Q which have equal size,
i.e. N/2 nodes each.
(ii) Both induced subgraph of P and Q are complete graphs.
(iii) P and Q are connected by exactly one edge.
Informally, a dumbbell is obtained by connecting two equal size complete graphs with an edge.
For example, consider graph A in Figure 1 with 10 nodes and 21 edges. There are two disjoint
complete graphs of size 5 which are connected by an edge. Therefore, this graph is a dumbbell. Graph
B and C are also dumbbells. Graph D, on the other hand, is not.
Figure 1.
Given a graph (which might be disconnected), determine how many connected components which
are dumbbells. A connected component is a connected subgraph which no vertex can be added and
still be connected.
Input
The first line of input contains an integer T (T ≤ 50) denoting the number of cases. Each case begins
with two integers: N and M (1 ≤ N ≤ 100; 0 ≤ M ≤ 4, 950) denoting the number of nodes and edges
in the graph respectively. The nodes are numbered from 1 to N. The following M lines each contains
two integer: a and b (1 ≤ a, b ≤ N; a ̸= b) representing an undirected edge connecting node a and node
b. You are guaranteed that each pair of nodes has at most one edge in the graph.
Output
For each case, output ‘Case #X: Y ’, where X is the case number starts from 1 and Y is the number
of connected components which are dumbbells for the respective case.
Explanation for 1st sample case:
There is only one node in the graph; a dumbbell requires at least two nodes.
Explanation for 2nd sample case:
Both connected components are dumbbells: {1, 2} and {3, 4}.
Explanation for 3rd sample case:
There are two connected components: {1, 2, 3, 4, 5, 6}, and {7, 8, 9, 10}, and both of them are
dumbbells. The first one is dumbbell with complete graph of size 3, while the second one has size of 2.
Explanation for 4th sample case:
There are four connected components: {1, 2}, {3, 4}, {5, 6} and {7, 8, 9}. Only the first three are
dumbbells.
Sample Input
4
1 0
4 2
1 2
3 4
10 10
1 2
1 3
2 3
3 4
4 5
5 6
4 6
7 8
8 9
9 10
9 5
1 2
3 4
5 6
7 8
8 9
Sample Output
Case #1: 0
Case #2: 2
Case #3: 2
Case #4: 3
Hint
题意
给你个无向图,问里面有多少个子图,满足里面可以分成P,Q两个连通块,且这两个PQ都是完全图,且两个图都由一条边连接,且俩完全图的size相同。
题解:
跑桥,然后看看桥两边的连通块长什么样子,然后特判断一下4个点的情况……
代码
#include <bits/stdc++.h>
#define rep(a,b,c) for(int (a)=(b);(a)<=(c);++(a))
#define drep(a,b,c) for(int (a)=(b);(a)>=(c);--(a))
#define pb push_back
#define mp make_pair
#define sf scanf
#define pf printf
#define two(x) (1<<(x))
#define clr(x,y) memset((x),(y),sizeof((x)))
#define dbg(x) cout << #x << "=" << x << endl;
#define lowbit(x) ((x)&(-x))
const int mod = 1e9 + 7;
int mul(int x,int y){return 1LL*x*y%mod;}
int qpow(int x , int y){int res=1;while(y){if(y&1) res=mul(res,x) ; y>>=1 ; x=mul(x,x);} return res;}
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
using namespace std;
const int maxn = 100 + 15;
int mat[maxn][maxn],N,M,vis[maxn],low[maxn],dfn[maxn],ti,label[maxn],rt,head[maxn],tot,sz[maxn];
vector < int > block,dcc[maxn];
stack < int > sp;
struct edge{
int v , nxt , isbrige;
}e[maxn * maxn * 5];
void dfs( int x ){
if( vis[x] ) return ;
vis[x] = 1;
block.pb( x );
for(int i = head[x] ; ~i ; i = e[i].nxt){
int v = e[i].v;
dfs( v );
}
}
void predfs( int x , int pr ){
dfn[x] = low[x] = ++ ti;
sp.push( x );
for(int i = head[x] ; ~i ; i = e[i].nxt){
int v = e[i].v;
if( i == ( pr ^ 1 ) ) continue;
if( !dfn[v] ){
predfs( v , i );
low[x] = min( low[x] , low[v] );
if( low[v] > dfn[x] ) e[i].isbrige = e[i ^ 1].isbrige = 1;
}else if( dfn[v] < dfn[x] ) low[x] = min( low[x] , dfn[v] );
}
if( low[x] == dfn[x] ){
int u;
++ rt;
do{
u = sp.top() ; sp.pop();
label[u] = rt;
}while( u != x );
}
}
bool judge( vector < int > & a ){
for(int i = 0 ; i < a.size() ; ++ i)
for(int j = i + 1 ; j < a.size() ; ++ j)
if( mat[a[i]][a[j]] == 0 )
return false;
return true;
}
int solve( int base ){
block.clear();
dfs( base );
if( block.size() == 4 ){
vector < int > dp;
for( auto it : block ) dp.pb( sz[it] );
sort( dp.begin() , dp.end() );
if( dp[0] == 1 && dp[1] == 1 && dp[2] == 2 && dp[3] == 2 ) return true;
return false;
}
ti = rt = 0;
predfs( base , 999999999 ); int bridgenum = 0;
for(auto it : block){
for(int i = head[it] ; ~i ; i = e[i].nxt) if( e[i].isbrige ) ++ bridgenum;
}
bridgenum >>= 1;
if( bridgenum == 0 || bridgenum > 3 ) return 0;
if( (int)block.size() & 1 ) return 0;
for(int i = 1 ; i <= rt ; ++ i) dcc[i].clear();
for(auto it : block) dcc[label[it]].pb( it );
if( bridgenum == 1 ){
if( dcc[1].size() != dcc[2].size() ) return 0 ;
if( !judge(dcc[1]) || !judge( dcc[2] )) return 0;
}else if( bridgenum == 2 ){
return 0;
}else if( bridgenum == 3 ){
if( block.size() != 4 ) return 0;
}
return 1;
}
void link( int u , int v ){
e[tot].isbrige=0,e[tot].v=v,e[tot].nxt=head[u],head[u]=tot++;
}
int main(int argc,char *argv[]){
int T=read(),cas=0;
while(T--){
N=read(),M=read();
rep(i,1,N) rep(j,1,N) mat[i][j]=0;
clr(head,-1);
clr(sz,0);
clr(label,0);
clr(dfn,0);
clr( vis , 0 );
tot = 0;
rep(i,1,M){
int u , v ;
sf("%d%d",&u,&v);
mat[u][v] = mat[v][u] = 1;
sz[u] ++ ;
sz[v] ++ ;
link( u , v );
link( v , u );
}
int ans = 0;
rep(i,1,N) if(!vis[i]) ans += solve( i );
pf("Case #%d: %d\n", ++ cas , ans );
}
return 0;
}
UVALive 6907 Body Building tarjan的更多相关文章
- UVALive 6907 Body Building
题目链接:https://vjudge.net/problem/UVALive-6907 题意: 给出一张图,判断这张图中有多少个哑铃,哑铃判断的条件是,对于一个连通图:如果找到一条边连接这两个点的个 ...
- UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】
Road Networks Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Stat ...
- Tarjan UVALive 6511 Term Project
题目传送门 /* 题意:第i个人选择第a[i]个人,问组成强联通分量(自己连自己也算)外还有多少零散的人 有向图强联通分量-Tarjan算法:在模板上加一个num数组,记录每个连通分量的点数,若超过1 ...
- UVALive 5135 Mining Your Own Bussiness【tarjan点双】
LINK1 LINK2 题目大意 给你一个无向连通图,让你给一些点染上黑色,需要满足染色之后,断开任意一个节点,要满足任意一个联通块中剩下的节点中至少有一个黑点 思路 一开始想的是把每一个点双联通分量 ...
- UvaLive 5026 Building Roads
传送门 Time Limit: 3000MS Description There is a magic planet in the space. There is a magical country ...
- UVALive - 4108 SKYLINE[线段树]
UVALive - 4108 SKYLINE Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug ...
- tarjan算法求桥双连通分量 POJ 3177 Redundant Paths
POJ 3177 Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12598 Accept ...
- HDU 4612 Warm up tarjan缩环+求最长链
Warm up Problem Description N planets are connected by M bidirectional channels that allow instant ...
- cdoj 92 Journey tarjan/lca 树上点对距离
Journey Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/92 Descri ...
随机推荐
- 流媒体技术学习笔记之(九)减少VLC 延迟的方法
之前写过一篇关于在Linux平台上编译Android平台上VLC播放器源代码的文章,vlc这款播放器非常优秀而且是开源的,它的核心是开源视频编解码库ffmpeg.而且这款播放器还支持RTSP协议,这个 ...
- mongodb的认证(authentication)与授权(authorization)
一小白瞎整mongodb,认证部分被折磨的惨不忍睹,看厮可怜,特查了一下文档,浅显地总结一下mongodb认证(authentication)与授权(authorization)的联系. 创建的所有用 ...
- html5 canvas缩放变换
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Firefox滚动残影(转)
Firefox滚动残影 Firefox滚动残影这文章放在草稿箱有一阵子了,之前的3系列都有这BUG,当正想发表这文章的时候,和我沟通刚刚升级的FF4已修复此BUG,所以搁置一阵在考虑到这文章还有没 ...
- Asp.net操作Word文档,原来这么简单啊!
引用Word对象库文件 具体做法是打开菜单栏中的项目>添加引用>浏览,在打开的“选择组件”对话框中找到MSWORD.OLB后按确定即可引入此对象库文件,vs.net将会自动将库文件转化为 ...
- Java笔记之java.lang.String#trim
String的trim()方法是使用频率频率很高的一个方法,直到不久前我不确定trim去除两端的空白符时对换行符是怎么处理的点进去看了下源码的实现,才发现String#trim的实现跟我想像的完全不一 ...
- C. Ayoub and Lost Array(DP)
(又是被队友带着上分的一场--) 题目链接:http://codeforces.com/contest/1105/problem/C 题目大意:给你n,l,r.每一个数都是在l,r范围之内,然后问你这 ...
- 关于golang的defer的练习
golang的defer怎么说.大意就是在函数return后.函数关闭前.按照filo的顺序来执行的关键字 上代码: package main import ( "fmt" ) f ...
- MapReduce--shuffle
一.Shuffle简介 Shuffle的正常意思是洗牌或弄乱,shuffle的大致范围就是把map task的输出结果有效的传送到Reduce端.也可以这样理解,shuffle描述着数据从map ta ...
- innobackupex不停库的数据备份并恢复到别的服务器上【转】
1.innobackupex原理: 备份原理 1).首先会开启一个后台检测进程,实时检测myql redo的变化,一旦发现redo中有新日志写入,立即将日志记入后台日志文件xtrabackup_log ...