zoukankan      html  css  js  c++  java
  • 解题报告 树形图计数

    1.        题目

    树形图计数

    count.pas/c/cpp

     

    【问题描述】

    k同学最近正在研究最小树形图问题。所谓树形图,是指有向图的一棵有根的生成树,其中树的每一条边的指向恰好都是从根指向叶结点的方向。现在小k在纸上画了一个图,他想让你帮忙数一下这个图有多少棵树形图。

     

    【输入格式】

    1行输入1个正整数:n,表示图中点的个数

    2~n+1行每行输入n个字符,描述了这个图的邻接矩阵。第i+1行第j个字符如果是0则表示没有从i连向j的有向边,1表示有一条从ij的有向边。

     

    【输出格式】

    输出11个整数,表示这个有向图的树形图个数。

     

    【样例输入】

    count.in

    4

    0100

    0010

    0001

    1000

     

    【样例输出】

    count.out

    4

     

    【数据规模和约定】

    对于100%的数据,n<=8 .

    2.        算法

    以每一个节点为根,判断从这个根开始用有向边能不能找到所有节点,如果能则记录。

     

    判断方法:首先将这棵树构建出来,也就是轮流将该点的入度所连的点作为他的父亲节点,看可不可以将这棵树构建出来,如果可以,再看构建出来的树能不能找到所有节点。

    3.        注意事项

    要先将这棵树构建出来,再判断。

    4.        代码

    深搜+判断(ASDF)

    program asdf;

      var

        b,a:array[0..10,0..10]of longint;

        f,ff:array[0..10]of boolean;

        fa:array[0..10]of longint;

        n,i,j,k,root:longint;

        all,sum,ans:qword;

        flag:boolean;

        ch:char;

      function judge:boolean;

        var

          i,x:longint;

        begin

          fillchar(f,sizeof(f),false);

          f[root]:=true;

          for i:=1 to n do

            begin

              fillchar(ff,sizeof(ff),false);

              x:=fa[i];

              while (fa[x]<>root)and(not f[fa[x]])and(fa[x]<>0) do

                begin

                  if ff[x] then exit(false);

                  ff[x]:=true;

                  x:=fa[x];

                end;

              if fa[x]=0 then exit(false);

              if (fa[x]=root)or(f[fa[x]]) then

                begin

                  x:=i;

                  while not f[x] do

                    begin

                      f[x]:=true;

                      x:=fa[x];

                    end;

                end;

            end;

          exit(true);

        end;

      procedure dfs(x:longint);

        var

          i:longint;

        begin

          if x=root then

            begin

              dfs(x+1);

              exit;

            end;

          if x=n+1 then

            begin

              if judge then inc(ans);

              exit;

            end;

          for i:=1 to n do

            if b[i,x]<>0 then

              begin

                fa[x]:=i;

                dfs(x+1);

              end;

        end;

      begin

        assign(input,'count.in');reset(input);

        assign(output,'count.out');rewrite(output);

        readln(n);

        for i:=1 to n do

          begin

            for j:=1 to n do

              begin

                read(ch);

                if ch='1' then b[i,j]:=1

                else b[i,j]:=0;

              end;

            readln;

          end;

        for root:=1 to n do

          begin

            flag:=false;

            for i:=1 to n do

              if b[root,i]<>0 then

                begin

                  flag:=true;

                  break;

                end;

            fa[root]:=root;

            if flag then

              dfs(1);

          end;

        write(ans);

        close(input);

        close(output); 

      end.

     

  • 相关阅读:
    Linux用户行为日志审计
    日志分析-Web
    secedit.exe 本地审核
    StreamCQL
    一个关于缓存很好的文章~
    Java免费开源数据库、Java嵌入式数据库、Java内存数据库
    MySQL db优化
    威胁情报
    《javascript设计模式》读书笔记二(封装和隐藏信息)
    Mysql触发器
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2213100.html
Copyright © 2011-2022 走看看