题目1495:关键点

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
 
#define NSIZE 10010
#define MSIZE 100010
 
typedef struct node {
    int link ;
    int next ;
} node ;
 
node data[2*MSIZE] ;
int datap ; int links[NSIZE] ;
 
int dis_s[NSIZE] , dis_t[NSIZE] ;
int q[NSIZE] , visit[NSIZE] ;
 
int n , m , s , t ;
 
inline int get_new()
{
    return datap ++ ;
}
 
int add_edge( int a , int b )
{
    int new_id = get_new() ;
    data[new_id].link = b ;
    data[new_id].next = links[a] ;
    links[a] = new_id ;
    return 0 ;
}
 
int extend_normal( int start , int dis[] )
{
    for ( int i = 1 ; i <= n ; i ++ ) {
        dis[i] = -1 ;
    }
    dis[start] = 0 ;
    int head = 0 ;
    int tail = 1 ;
    q[head] = start ;
    memset( visit , 0 , sizeof(visit) ) ;
    visit[start] = 1 ;
    while ( tail > head ) {
        int cur_node = q[head] ;
        int next = links[cur_node] ;
        while ( next != -1 ) {
            int next_node = data[next].link ;
            if ( !visit[next_node] ) {
                q[tail] = next_node ;
                dis[next_node] = dis[cur_node]+1 ;
                visit[next_node] = 1 ;
                tail ++ ;
            }
            next = data[next].next ;
        } 
        head ++ ;
    }
}
 
int proc_one()
{
    if ( scanf( "%d%d%d%d" , &n , &m , &s , &t ) == EOF ) {
        return 0 ;
    }
    for ( int i = 1 ; i <= n ; i ++ ) {
        links[i] = -1 ;
    }
    datap = 0 ;
    for ( int i = 0 ; i < m ; i ++ ) {
        int a , b ;
        scanf( "%d%d" , &a , &b ) ;
        add_edge( a , b ) ;
        add_edge( b , a ) ;
    }
    extend_normal( s , dis_s ) ;
    extend_normal( t , dis_t ) ;
    int min_dis = dis_s[t] ; // should be equal to dis_t[s]
    if ( min_dis == -1 ) {
        printf( "0\n" ) ;
        return 1 ;
    }
 
    // do final extend
    int head = 0 ; 
    int tail = 1 ;
    q[head] = s ;
    int disl = 0 ; 
    int disr = min_dis ;
    memset( visit , 0 , sizeof(visit) ) ;
    visit[s] = 1 ;
    int ans = 0 ;
    while ( 1 ) {
        int ori_tail = tail ;
        for ( int i = head ; i < ori_tail ; i ++ ) {
            int cur_node = q[i] ;
            int next = links[cur_node] ;
            while ( next != -1 ) {
                int next_node = data[next].link ; 
                if ( visit[next_node] ) {
                    next = data[next].next ;
                    continue ;
                }
                if ( dis_s[next_node] != disl + 1 || dis_t[next_node] != disr - 1 ) {
                    next = data[next].next ;
                    continue ;
                }
                q[tail] = next_node ;  
                visit[next_node] = 1 ;
                tail ++ ;
                next = data[next].next ;
            }
        }
        if ( visit[t] ) {
            break ;
        }
        head = ori_tail ;
        if ( tail - head == 1 ) {
            ans ++ ;
        }
        disl ++ ;
        disr -- ;
    }
    printf( "%d\n" , ans ) ;
    return 1 ;
}
 
int main()
{
    while ( proc_one() ) {
        ;
    }
    return 0 ;
}
/**************************************************************
    Problem: 1495
    User: cust123
    Language: C++
    Result: Accepted
    Time:190 ms
    Memory:2780 kb
****************************************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值