Aizu - ALDS1_11_B(DFS)

题目链接:https://cn.vjudge.net/problem/Aizu-ALDS1_11_B  白书2 p224

题目:

Depth-first search (DFS) follows the strategy to search ”deeper” in the graph whenever possible. In DFS, edges are recursively explored out of the most recently discovered vertex vv that still has unexplored edges leaving it. When all of vv's edges have been explored, the search ”backtracks” to explore edges leaving the vertex from which vv was discovered.

This process continues until all the vertices that are reachable from the original source vertex have been discovered. If any undiscovered vertices remain, then one of them is selected as a new source and the search is repeated from that source.

DFS timestamps each vertex as follows:

  • d[v]d[v] records when vv is first discovered.
  • f[v]f[v] records when the search finishes examining vv’s adjacency list.

Write a program which reads a directed graph G=(V,E)G=(V,E) and demonstrates DFS on the graph based on the following rules:

  • GG is given in an adjacency-list. Vertices are identified by IDs 1,2,...n1,2,...nrespectively.
  • IDs in the adjacency list are arranged in ascending order.
  • The program should report the discover time and the finish time for each vertex.
  • When there are several candidates to visit during DFS, the algorithm should select the vertex with the smallest ID.
  • The timestamp starts with 1.

Input

In the first line, an integer nn denoting the number of vertices of GG is given. In the next nn lines, adjacency lists of uu are given in the following format:

uu kk v1v1 v2v2 ... vkvk

uu is ID of the vertex and kk denotes its degree. vivi are IDs of vertices adjacent to uu.

Output

For each vertex, print idid, dd and ff separated by a space character in a line. idid is ID of the vertex, dd and ff is the discover time and the finish time respectively. Print in order of vertex IDs.

Constraints

  • 1≤n≤1001≤n≤100

Sample Input 1

4
1 1 2
2 1 4
3 0
4 1 3

Sample Output 1

1 1 8
2 2 7
3 4 5
4 3 6

Sample Input 2

6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0

Sample Output 2

1 1 12
2 2 11
3 3 8
4 9 10
5 4 7
6 5 6

This is example for Sample Input 2 (discover/finish)

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

题意:

如上图

第一行输入G的顶点数n。接下来n行按如下格式输入各顶点u的邻接表 u k v1 v2 .......

其中u为顶点编号,k为u的出度,v1 v2 v3...... 为与u相邻的顶点编号

用DFS做 有两种方法  用栈实现 和 用递归实现

代码:

用栈实现:

#include <iostream>
#include <string>
#include <string.h>
#include <stack>
#include <stdio.h>
using namespace std;
int n,pic[105][105],u,k,v,vis[105],flag=0,d[105],f[105];
int step=0;

void dfs(int i)
{
    stack <int> s;
    while(!s.empty())s.pop();
    s.push(i);
    vis[i]=1;
    step++,d[i]=step;
    while(!s.empty())
    {
        int t=s.top();
        flag=0;
        for(int j=1; j<=n; j++)
        {
            if(pic[t][j]==1 && vis[j]==0)
            {
                s.push(j);
                step++,d[j]=step;
                vis[j]=1;
                flag=1;
                break;
            }
        }
        if(flag==0)
        {
            s.pop();
            step++,f[t]=step;
        }
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; i++)
        {
            scanf("%d %d",&u,&k);
            for(int j=0; j<k; j++)
            {
                scanf("%d",&v);
                pic[u][v]=1;
            }
        }
        for(int i=1; i<=n; i++)
        {
            if(vis[i]==0)dfs(i);
        }

        for(int i=1; i<=n; i++)
            printf("%d %d %d\n",i,d[i],f[i]);
    }
    return 0;
}

用递归实现:

#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
int n;
bool ok[10005];
int d[10005],f[10005];
vector <int> e[10005];
int step=0;
void dfs(int i)
{
    ok[i]=1;
    step++;
    d[i]=step;
    for(int j=0;j<e[i].size();j++)
        if(!ok[e[i][j]])
            dfs(e[i][j]);
    step++;
    f[i]=step;
}
void solve()
{
    for(int i=1;i<=n;i++)
        if(!ok[i])dfs(i);
    for(int i=1;i<=n;i++)
        printf("%d %d %d\n",i,d[i],f[i]);
}

int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d",&n);
    int u,k,v;
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&u,&k);
        for(int j=0;j<k;j++)
        {scanf("%d",&v);e[u].push_back(v);}
    }
    solve();
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值