#sicily#1004. Forest

来源:http://soj.sysu.edu.cn/show_problem.php?pid=1004&cid=2387

hit

1.先找到每棵树的根再BFS,不然就有可能出现把一棵好树判断为非法树的情况。
2.树不合法有两种情况:(1)有环,(2)交叉;
3.树不合法的判断方法:(1)BFS时访问已访问之节点:交叉和环不含根节点的情况 (2)BFS结束后,仍有NODE未访问:环包含根节点的情况

代码

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

int vectorNum, edgeNum;
bool isVisited[101];
bool adjMatrix[101][101];
int depth[101];
int levelWidth[101];
bool valid;

void bfs(int start);
bool isRoot(int node);
bool allVisited();

int main() {
    while (cin >> vectorNum >> edgeNum && vectorNum != 0) {
        // initialize
        valid = true;
        memset(isVisited, false, 101*sizeof(bool));
        memset(adjMatrix, false, 101*101*sizeof(bool));
        memset(depth, 0, 101*sizeof(int));
        memset(levelWidth, 0, 101*sizeof(int));
        // read edges
        int a, b;
        for (int i = 0; i < edgeNum; i++) {
            cin >> a >> b;
            adjMatrix[a][b] = true;
        }
        //bfs
        for(int i = 1; (i <= vectorNum) && valid; i++) {
            if (false == isVisited[i] && isRoot(i)) bfs(i);
        }
        // output
        if ((!valid) || (!allVisited())) {
            cout << "INVALID" << endl;
        } else {
            int forestWidth = -1;
            int level = 0;
            for (;levelWidth[level] != 0;level++) {
                if (levelWidth[level] > forestWidth) forestWidth = levelWidth[level];
            }
            cout << level - 1 << ' ' << forestWidth << endl;
        }
    }
    return 0;
}

void bfs(int start) {
    queue<int> q;
    q.push(start);
    depth[start] = 0;
    levelWidth[depth[start]]++;

    int node;
    while (!q.empty()) {
        node = q.front();
        isVisited[node] = true;
        q.pop();
        for (int i = 1; i <= vectorNum; i++) {
            if (adjMatrix[node][i]) {
                // the loop  || to edge point to the same vector
                if (!isVisited[i]) {
                    q.push(i);
                    depth[i] = depth[node] + 1;
                    levelWidth[depth[i]]++;
                } else {
                    valid = false; 
                    return;
                }
            }
        }
    }
    return;
}

bool isRoot(int node) {
    for (int i = 1; i <= vectorNum; i++) {
        if (adjMatrix[i][node]) return false;
    }
    return true;
}

// if valid , every node should have been visited
bool allVisited() {
    for (int i = 1; i <= vectorNum; i++) {
        if (!isVisited[i]) return false;
    }
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值