2016年8月28日 星期日

商競103M-P31是否為樹(VB版參考)

這是依商業技藝競賽程式103年模擬題第3題子題1稍微修改
資料檔第1列 一個數字 n ,代表 n 組資料{0<n<10},接著每組資料一列
每列是一個圖形的所有「邊」以空白隔開 ,每一個「邊」是由兩數字以逗號連接
判斷這個圖形是否為一棵樹,是印T否印F

參考程式碼:
   'b517: 是否為樹-商競103 標籤 : dfs tree
    '這是 103年商業技藝競賽模擬題的 P31題,原題中對樹的描述就先省略了。
    '給一個圖形的邊的資訊,判斷是否為一棵樹?
    '輸入說明 : 每組測資檔的第1列為一個數字 n ,代表以下有 n 列,每列為一個圖形的相鄰節點(邊)的資訊:
    '每列中的所有邊皆由 i,j 表示,邊與邊之間以空格隔開, 0<=i,j <=80, i及j為相鄰的兩節點編號,以「,」連接i,j不含空格
    '輸出說明 : 對於每一個圖形輸出一列,判斷其是否為一棵樹,若是則輸出 T 、否則輸出 F

    Const MaxN As Integer = 80
    Dim adj(MaxN, MaxN) As Boolean '相鄰矩陣
    Dim nd(MaxN) As Boolean  '有編號的節點
    Sub dfs(ByVal u As Integer)
        nd(u) = False  '訪過設為 false
        For v = 0 To MaxN
            If adj(u, v) And nd(v) Then 'u的鄰邊且未訪過的 v 遞迴 dfs
                dfs(v)
            End If
        Next
    End Sub
 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  FileOpen(1, "in1.txt", OpenMode.Input)
 ' FileOpen(2, "in2.txt", OpenMode.Input)  本題改為1檔
  FileOpen(3, "out.txt", OpenMode.Output)
  For fn = 1 To 1  '本題改為1檔
      If fn = 2 Then PrintLine(3)
      Dim n As Short = LineInput(fn) ' n 筆資料
    '  Array.Clear(adj, False, (MaxN + 1) * (MaxN + 1)) '<<需放入 do 迴圈內
    '  Array.Clear(nd, False, (MaxN + 1))               '<<需放入 do 迴圈內
    Do Until n = 0
       Array.Clear(adj, False, (MaxN + 1) * (MaxN + 1)) '2017/11/17更正

       Array.Clear(nd, False, (MaxN + 1))               '2017/11/17更正
        n -= 1
       Dim egs() = LineInput(fn).Split(" ") '每一行以空格分成多個邊字串egs()
       Dim vn As Integer = 0, en As Integer = egs.Length '節點的個數 、邊的個數
       Dim st As Integer  ' 任選一個 dfs的起點
       For i = 0 To en - 1  '每個邊有兩個節點 x,y
          Dim xy() = egs(i).Split(",")
           Dim x As Integer = xy(0), y As Integer = xy(1)
           nd(x) = True : nd(y) = True
            adj(x, y) = True : adj(y, x) = True
            st = x
        Next
        For i = 0 To MaxN  '算節點的個數
           If nd(i) Then vn += 1
         Next
        If vn <> en + 1 Then '節點數 < > 邊的個數+1  非樹
            PrintLine(3, "F")
            Continue Do '下一組
         End If
         Dim conn As Boolean = True  '有連通
         dfs(st)       ' 呼叫 dfs 測試是否連通
         For i = 0 To MaxN
           If nd(i) Then
               conn = False
               Exit For
           End If
         Next
         PrintLine(3, IIf(conn, "T", "F"))
     Loop  ' do until n
   Next ' for fn 
   End

End Sub
輸入in1.txt (VB原題有兩個檔,改為一個,且邊之間的空格改為只有1個)
8
6,8 5,3 5,2 6,4 5,6 1,2 2,0
8,1 1,3 6,2 8,10 7,5 1,4 7,8 7,6 8,0
3,8 6,8 6,4 5,3 5,6 8,2 2,0
1,0 4,3 1,2
4,3 2,3 2,1 1,0
1,2 2,3 4,0
1,2 2,3 3,1 4,5 5,0

2,5 1,3 2,6 4,1 3,6
輸出out.txt
T
T
F
F
T
F
F

T

2 則留言: