Advertisement
Pug_coder

CriticalWay

Apr 27th, 2021
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 6.29 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "github.com/skorobogatov/input"
  6.     "sort"
  7.     "strconv"
  8. )
  9. type peak struct{
  10.     name string;
  11.     comp int;
  12.     list []*peak;
  13.     T1 int;
  14.     low int;
  15.     value int;
  16.     color int;
  17.     sum int;
  18.     marker bool;
  19.     list_sum []*peak;
  20.     out []*peak;
  21. }
  22. type arrPeak [] * peak
  23. func partiton( low int, high int, less func(i, j int )bool, swap func(i, j int)) int{
  24.     i := low
  25.     for j := low; j < high; j++ {
  26.         if less(j,high) {
  27.             swap(i,j)
  28.             i++
  29.         }
  30.     }
  31.     swap(i,high)
  32.     return i
  33. }
  34. func quickSortRec(low int, high int, less func(i, j int) bool, swap func(i, j int)){
  35.     if low < high{
  36.         q := partiton(low, high, less ,swap)
  37.         quickSortRec(low , q - 1, less, swap)
  38.         quickSortRec( q + 1, high, less, swap)
  39.     }
  40. }
  41. func QuickSort(n int, less func(i, j int) bool,swap func(i, j int)) {
  42.     quickSortRec(0, n - 1, less, swap)
  43. }
  44.  
  45. var time = 1
  46. var count = 1
  47. var index = 0
  48. var stack arrPeak
  49. func Tarjan(l arrPeak, stack arrPeak){
  50.     for _, v := range l{
  51.         if v.T1 == 0{
  52.             VisitVertex_Tarjan(l, v, stack)
  53.         }
  54.     }
  55. }
  56.  
  57. func VisitVertex_Tarjan(l arrPeak, v *peak, stack arrPeak){
  58.     v.T1 = time
  59.     v.low = time
  60.     time++
  61.     stack[index] = v
  62.     index++
  63.     for _, i := range v.list{
  64.         u := i
  65.         if u.T1 == 0{
  66.             VisitVertex_Tarjan(l, u, stack)
  67.         }
  68.         if u.comp == 0 && v.low > u.low{
  69.             v.low = u.low
  70.         }
  71.     }
  72.     if v.T1 == v.low{
  73.         index--
  74.         u := stack[index]
  75.         u.comp = count
  76.         for u != v{
  77.             index--
  78.             u = stack[index]
  79.             u.comp = count
  80.         }
  81.         count++
  82.     }
  83. }
  84.  
  85. func dfs(data_name arrPeak){
  86.     queue := make(arrPeak, len(data_name))
  87.     indexin := 0
  88.     for _, w := range data_name{
  89.         if !w.marker && w.color == -1{
  90.             w.marker = true
  91.             queue[indexin] = w
  92.             indexin++
  93.             for indexin > 0{
  94.                 indexin--
  95.                 v := queue[indexin]
  96.                 for _, u := range v.list{
  97.                     if ! u.marker{
  98.                         u.marker = true
  99.                         queue[indexin] = u
  100.                         indexin++
  101.                         u.color = -1
  102.                     }
  103.                 }
  104.             }
  105.         }
  106.     }
  107. }
  108. func in(t *peak, out arrPeak) bool{
  109.     for _, i := range out{
  110.         if i == t{
  111.             return true
  112.         }
  113.     }
  114.     return false
  115. }
  116. func (arr arrPeak) Len() int {return len(arr)}
  117. func (arr arrPeak) Less(i,j int) bool {
  118.     a, b := arr[i].sum, arr[j].sum
  119.     return a > b
  120. }
  121. func (arr arrPeak) Swap(i, j int) {
  122.     arr[i], arr[j] = arr[j], arr[i]
  123. }
  124. func sortedSum(data arrPeak){
  125.     if len(data) > 1{
  126.         sort.Sort(data)
  127.     }
  128. }
  129. func sortedName(data arrPeak){
  130.     if len(data) > 1{
  131.         QuickSort(len(data) ,
  132.             func (i, j int) bool {
  133.                 return data[i].name < data[j].name},
  134.             func (i, j int) { data[i], data[j] = data[j], data[i]},
  135.         )
  136.     }
  137. }
  138. func main() {
  139.     symbol := ';'
  140.     data_name := make(arrPeak, 0)
  141.     for symbol == ';'{
  142.         str := input.Gets()
  143.         for str[len(str)-1] == '<'{
  144.             str += input.Gets()
  145.         }
  146.         name := &peak{}
  147.         i := 0
  148.         symbol = '.'
  149.         for i < len(str){
  150.             if str[i] == '('{
  151.                 j := i+1
  152.                 for j = i+1; str[j] != ')'; j++{
  153.                 }
  154.                 name.value, _ = strconv.Atoi(str[i+1: j])
  155.                 i = j
  156.             }else if (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'){
  157.                 j := i
  158.                 for j < len(str) && str[j] != ';' && str[j] != '(' && str[j] != ' '{
  159.                     j++
  160.                 }
  161.                 n := str[i:j]
  162.                 flag := 0
  163.                 var k *peak
  164.                 for _, chek := range data_name{
  165.                     if chek.name == n{
  166.                         flag = 1
  167.                         k = chek
  168.                         break
  169.                     }
  170.                 }
  171.                 if flag == 0{
  172.                     k = &peak{
  173.                         name: n,
  174.                         comp: 0,
  175.                         T1: 0,
  176.                         color: 0,
  177.                         sum: 0,
  178.                         marker: false,
  179.                     }
  180.                     data_name = append(data_name, k)
  181.                 }
  182.                 if name != nil{
  183.                     if name.name == k.name{
  184.                         name.color = -1
  185.                     }
  186.                     flag = 1
  187.                     for _, h := range name.list{
  188.                         if h == k{
  189.                             flag = 0
  190.                         }
  191.                     }
  192.                     if flag == 1{
  193.                         name.list = append(name.list, k)
  194.                     }
  195.                 }
  196.                 name = k
  197.                 i = j
  198.             }else if str[i] == ' ' || str[i] == '<'{
  199.                 i++
  200.             }else if str[i] == ';'{
  201.                 symbol = ';'
  202.                 i++
  203.             }else{
  204.                 i++
  205.             }
  206.         }
  207.     }
  208.     stack = make(arrPeak, len(data_name))
  209.     Tarjan(data_name, stack)
  210.     inf := make([]int, count)
  211.  
  212.     for _, i := range data_name{
  213.         inf[i.comp - 1]++
  214.     }
  215.     for _, i := range data_name{
  216.         if inf[i.comp - 1] >= 2{
  217.             i.color = -1
  218.             for _, j := range i.list{
  219.                 j.color = -1
  220.             }
  221.         }
  222.     }
  223.     dfs(data_name)
  224.     queue := make(arrPeak, len(data_name))
  225.     indexin := 0
  226.     for _, w := range data_name{
  227.         if !w.marker && w.color != -1{
  228.             w.marker = true
  229.             queue[indexin] = w
  230.             indexin++
  231.             w.list_sum = append(w.list_sum, w)
  232.             w.sum = w.value
  233.             for indexin > 0{
  234.                 indexin--
  235.                 v := queue[indexin]
  236.                 for _, u := range v.list{
  237.                     if u.color != -1 && (! u.marker || v.sum + u.value > u.sum){
  238.                         u.marker = true
  239.                         queue[indexin] = u
  240.                         indexin++
  241.                         u.sum = v.sum + u.value
  242.                         u.list_sum = make(arrPeak, 0)
  243.                         for _, k := range v.list_sum{
  244.                             u.list_sum = append(u.list_sum, k)
  245.                         }
  246.                         u.list_sum = append(u.list_sum, u)
  247.                         u.out = make(arrPeak, 0)
  248.                         u.out = append(u.out, v)
  249.                     }else if u.color != -1 && v.sum + u.value == u.sum{
  250.                         u.marker = true
  251.                         queue[indexin] = u
  252.                         indexin++
  253.                         u.out = append(u.out, v)
  254.                         for _, k := range v.list_sum{
  255.                             u.list_sum = append(u.list_sum, k)
  256.                         }
  257.                     }
  258.                 }
  259.             }
  260.         }
  261.     }
  262.     sortedSum(data_name)
  263.     max := data_name[0].sum
  264.     for _, i := range data_name{
  265.         if i.sum == max{
  266.             for _, k := range i.list_sum{
  267.                 k.color = 1
  268.             }
  269.         }else{
  270.             break
  271.         }
  272.     }
  273.     sortedName(data_name)
  274.     fmt.Println("digraph {")
  275.     for _, i := range data_name{
  276.         if i.color == 1{
  277.             a := i.name
  278.             fmt.Printf(`  %s [label = "%s(%d)", color = red]`, a, a, i.value)
  279.             fmt.Printf("\n")
  280.         }else if i.color == -1{
  281.             a := i.name
  282.             fmt.Printf(`  %s [label = "%s(%d)", color = blue]`, a, a, i.value)
  283.             fmt.Printf("\n")
  284.         }else{
  285.             a := i.name
  286.             fmt.Printf(`  %s [label = "%s(%d)"]`, a, a, i.value)
  287.             fmt.Printf("\n")
  288.         }
  289.     }
  290.     for _, t := range data_name{
  291.         if len(t.list) > 1{
  292.             QuickSort(  len(t.list) ,
  293.                 func (i, j int) bool {
  294.                     return t.list[i].name < t.list[j].name},
  295.                 func (i, j int) { t.list[i], t.list[j] = t.list[j], t.list[i]},
  296.             )
  297.         }
  298.         for _, i := range t.list{
  299.             if t.color == 1 && i.color == 1 && in(t, i.out){
  300.                 fmt.Printf("  %s -> %s [color = red]\n", t.name, i.name)
  301.             }else if t.color == -1 && i.color == -1{
  302.                 fmt.Printf("  %s -> %s [color = blue]\n", t.name, i.name)
  303.             }else {
  304.                 fmt.Printf("  %s -> %s\n", t.name, i.name)
  305.             }
  306.         }
  307.     }
  308.     fmt.Println("}")
  309. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement