soj 1034. Forest

来源:互联网 发布:2015nba西部决赛数据 编辑:程序博客网 时间:2024/05/24 16:16

方法来源:http://blog.csdn.net/guozhengchun/article/details/40761255


判断森林是否合法,以及找出最大宽度跟深度,上面博客的方法很好,是将森林变成树来处理的





#include <iostream>#include <cstring>#include <queue>using namespace std;struct node{    int dad; //父节点     int child_num; //子节点数     int child[101]; //子节点编号     node(){        dad=-1;          child_num=0;        for(int i=0; i < 101; ++i) child[i]=-1;    }};int main(){    int n,m;    while(cin >> n >> m){        node nn[101];        if(n==0) break;        if(m==0){            cout << "0 " << n << endl;            continue;        }//没有边时 深度为0,但宽度为所有节点数         int a,b;        for(int i=0; i < m; ++i){            cin >> a >> b;            nn[a].child[nn[a].child_num++] = b;//记录a的子节点为b             nn[b].dad=a;//b的父节点为a         }        bool check=false;//合法的         int bian=m;//合成树后的新总边数         for(int i=1; i <= n; ++i){            if(nn[i].dad==i){                check=true;                break;            }//节点的父节点为本身,是环不合法,结束             if(nn[i].dad==-1){                nn[i].dad=0;                nn[0].child[nn[0].child_num++]=i;                bian++;            }//没有父节点的节点,作为节点0的子节点,然后新总边数+1         }        if(n!=bian||check==true||m==bian){            cout << "INVALID" << endl;            continue;        }/* n!=bian说明存在入度不为1的节点,因为新树的节点数为n+1正常的话节点=边数+1,即n+1=bian+1,如果不是就是说明有入度超过1check==true说明有节点的父节点为本身m==bian说明所有节点构成一个环         */ queue<node> q;        q.push(nn[0]);        int maxwidth=-1;//记录最大的宽度,也就是我们要的结果         int pos=0;//当前结点在当前这一层的第几个位置,用于判断当前这层是否遍历完了         int nowwidth=1;//当点所在这层的宽度         int nextwidth=0;//下一层的宽度         int depth=-1;//深度,因为加了一个不存在的头节点,所以要从-1开始         int nodecount=0;//这棵树中总的节点数,用来判断是否存在环没有组成这颗树         node now;        while(!q.empty()){            now=q.front();            q.pop();            nodecount++;            for(int i=0; i < now.child_num; ++i)                    q.push(nn[now.child[i]]);//将下一层的节点入队             pos++;            nextwidth+=now.child_num;//计算下一层的节点数,也就是宽度             if(pos==nowwidth){//如果当前位置到了这一层的最后一个节点                 if(nextwidth > maxwidth)                    maxwidth=nextwidth;//更新最大的宽度                 nowwidth=nextwidth;//更新当前的宽度为下一层的宽度                 nextwidth=0;//将下一层的宽度初始化为0                 depth++;//深度加一                 pos=0;// 初始化记录的位置             }        }        if(nodecount-1==n){            cout << depth-1 << " " << maxwidth << endl;        }        else cout << "INVALID" << endl;//存在环没构成树     }} 


0 0
原创粉丝点击