您的位置:首页 > 其它

Sicily 4431. 有向图边的分类

2012-02-10 23:50 381 查看
有向图边的分类……什么来的,完全没概念。上网查了下,可知:

1. 树枝,是深度优先森林Gπ中的边,如果结点v是在探寻边(u,v)时第一次被发现,那么边(u,v)就是一个树枝。

2. 反向边,是深度优先树中连结结点u到它的祖先v的那些边,环也被认为是反向边。

3. 正向边,是指深度优先树中连接顶点u到它的后裔的非树枝的边。

4. 交叉边,是指所有其他类型的边,它们可以连结同一棵深度优先树中的两个结点,

只要一结点不是另一结点的祖先,也可以连结分属两棵深度优先树的结点。

http://www.ahhf45.com/info/data_structures_and_algorithms/algorithm/commonalg/graph/traversal/dfs.htm

然后就利用这些特点,使用深搜来解决。树枝和反向边都很好区分,前者是发现新节点的边,后者是回溯前节点的边。但关键在于区分有边相连的两个节点是否具有前后裔的关系,这是区分正向边和交叉边的重要依据。而我是用发现先后来进行判断的:在排除树枝和反向边后,对于边(u,v),若u先被发现,则这条边是正向边;否则,就是交叉边。

另:写代码还是比较麻烦,我的代码就有近1500字节,但在查看Status时,发现居然有200多字节的!发现是熟人后,便去求代码,然后被告知:这道题的测试数据只有样例给出的那个,直接把Sample Output输出就可以AC了……

Run Time: 0sec

Run Memory: 356KB

Code length: 1371Bytes

Submit Time: 2011-12-27 11:26:42

// Problem#: 4431
// Submission#: 1136604
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cstring>
using namespace std;

int n, m, k;
int u, v;
int time;
bool edge[ 101 ][ 101 ];
int visited[ 101 ];
int find[ 101 ];
int kind[ 101 ][ 101 ];

void DFS( int i ) {
time++;
for ( int j = 1; j <= n; j++ ) {
if ( edge[ i ][ j ] ) {
if ( visited[ j ] == 0 ) {
find[ j ] = time;
visited[ j ] = 1;
kind[ i ][ j ] = 1;
DFS( j );
}
else if ( visited[ j ] == 1 )
kind[ i ][ j ] = 3;
else if ( find[ i ] < find[ j ] )
kind[ i ][ j ] = 2;
}
}
visited[ i ] = 2;
time++;
}

int main()
{
char *s[ 4 ] = { "Cross Edge", "Tree Edge", "Down Edge", "Back Edge" };

memset( edge, false, sizeof( edge ) );
memset( visited, 0, sizeof( visited ) );
memset( kind, 0, sizeof( kind ) );

scanf( "%d%d", &n, &m );
while ( m-- ) {
scanf( "%d%d", &u, &v );
edge[ u ][ v ] = true;
}

time = 1;
for ( int i = 1; i <= n; i++ ) {
if ( visited[ i ] == 0 ) {
find[ i ] = time;
visited[ i ] = 1;
DFS( i );
}
}

scanf( "%d", &k );
while ( k-- ) {
scanf( "%d%d", &u, &v );
printf( "edge (%d,%d) is %s\n", u, v, s[ kind[ u ][ v ] ] );
}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: