Advertisement
Ladies_Man

Dominators

Jun 9th, 2014
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.05 KB | None | 0 0
  1. package main
  2. import "fmt"
  3. import "github.com/skorobogatov/input"
  4. import "container/list"  
  5. import "os"
  6.  
  7. type vertex struct {
  8.     x, indx, time                      int
  9.     dom, sdom, ancestor, label, parent *vertex
  10.     bucket                             []*vertex
  11.     in, out                            []int
  12. }
  13.  
  14. type stack struct {
  15.     data       []*vertex
  16.     cap, count int
  17.     top        *vertex
  18. }
  19.  
  20. var G map[int]*vertex
  21. var cycle map[int]bool
  22. var time,rs int = 1, 0
  23.  
  24. type Stack struct {
  25.      container *list.List
  26. }
  27. func NewStack() *Stack { return new(Stack).Init() }
  28. func (s *Stack) Init() *Stack {
  29.         s.container = list.New()
  30.         return s
  31. }
  32.  
  33. func DFS(ind int, p *vertex) {
  34.     G[ind].time, G[ind].parent = time, p
  35.     time++
  36.     for _, i := range G[ind].in { if G[i].time == 0 { DFS(i, G[ind]) } }
  37. }
  38.  
  39. func (s *Stack) Push(value interface{}) { s.container.PushBack(value) }
  40. func (s *Stack) Pop() interface{}       { return s.container.Remove(s.container.Back()) }
  41.  
  42. func FindMin(v *vertex, n int) (min *vertex) {
  43.         if v.ancestor == nil {
  44.         min = v
  45.     } else {
  46.             s, u := NewStack(), v
  47.             for u.ancestor.ancestor != nil { s.Push(u); u = u.ancestor }
  48.             for 0 != s.container.Len() {
  49.                 v = s.Pop().(*vertex)
  50.                 if v.ancestor.label.sdom.time < v.label.sdom.time { v.label = v.ancestor.label }
  51.                 v.ancestor = u.ancestor
  52.             }
  53.                 min = v.label
  54.     }
  55.     return
  56. }
  57.  
  58. func Dominators() {
  59.     temp := make([]*vertex, 0)
  60.     for _, w := range G {
  61.         w.sdom, w.label, w.ancestor = w, w, nil
  62.         if w.time != 0 && nil != w.parent { temp = append(temp, w) }
  63.     }
  64.     last := len(temp) - 1
  65.     for i := 0; i < last; i++ {
  66.         iMin := i
  67.         for j := i + 1; j < len(temp); j++ { if 0 != temp[j].time && 0 != temp[iMin].time && temp[j].time > temp[iMin].time { iMin = j } }
  68.         temp[i], temp[iMin] = temp[iMin], temp[i]
  69.     }
  70.     for _, w := range temp {
  71.         for _, index := range w.out { if u := FindMin(G[index], len(G)); u.sdom.time < w.sdom.time && 0 != G[index].time { w.sdom = u.sdom } }
  72.         w.ancestor = w.parent
  73.         w.sdom.bucket = append(w.sdom.bucket, w)
  74.         for _, v := range w.parent.bucket { if u := FindMin(v, len(G)); u.sdom == v.sdom { v.dom = w.parent } else { v.dom = u } }
  75.         w.parent.bucket = w.parent.bucket[:0]
  76.     }
  77.     for i := 1; i < len(temp); i++ { for j := i; j > 0 && temp[j].time < temp[j-1].time; j-- { temp[j-1], temp[j] = temp[j], temp[j-1] } }
  78.     for i := 0; i < len(temp); i++ { if w := temp[i]; w.dom != w.sdom { w.dom = w.dom.dom } }
  79. }
  80.  
  81. func nless2 (num int) bool {
  82.         var a int
  83.         if num < 3 {
  84.                 if 0 == num { os.Exit(1)
  85.                 } else if 1 == num {
  86.                     input.Scanf ("%d\n", &a)
  87.                     fmt.Printf ("0"); os.Exit(0)
  88.                 }
  89.         return false
  90.         } else { return true }
  91.         return true
  92. }
  93.  
  94. func main() {
  95.     var n, label, operand, val, start, prv int
  96.     var command string
  97.     input.Scanf("%d", &n)
  98.     if z:= nless2(n); !(z) { os.Exit(0) }
  99.     cycle = make(map[int]bool)
  100.     G = make(map[int]*vertex)
  101.     tmp := make([]int, n)
  102.     for i := 0; i < n; i++ {
  103.         input.Scanf("%d %s", &label, &command)
  104.         if 0 == i { start = label }
  105.         G[label] = new(vertex)
  106.         G[label].indx = label
  107.         if command == "ACTION" { val = 1 } else if command == "JUMP" { val = 2 } else { val = 3 }
  108.         G[label].x, tmp[i] = val, label
  109.         if 0 != prv  && 2 != G[prv].x { G[prv].in = append(G[prv].in, label) }
  110.         prv = label
  111.         if command == "BRANCH" || command == "JUMP" {
  112.             input.Scanf("%d", &operand)
  113.             G[label].in = append(G[label].in, operand)
  114.         }
  115.         input.Scanf("\n")
  116.     }
  117.     for i, k := range G { for _, j := range k.in { G[j].out = append(G[j].out, i) } }
  118.     DFS(start, nil)
  119.     Dominators()
  120.     for _,i := range tmp {
  121.                 if 0 != G[i].time  {
  122.                         v := G[i]
  123.                         for _, i := range v.out {
  124.                             dom := G[i]
  125.                         for dom != nil && dom != v { dom = dom.dom }
  126.                         if dom == v { cycle[v.indx], rs = true, rs + 1 }
  127.                     }
  128.                 }
  129.         }
  130.         fmt.Println(len(cycle))
  131. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement