Advertisement
osipyonok

Минимизация НКА без eps переходов

Jan 4th, 2017
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.92 KB | None | 0 0
  1. /* package whatever; // don't place package name! */
  2. // By Max Osipyonok
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6.  
  7. /* Name of the class has to be "Main" only if the class is public. */
  8. class Main
  9. {
  10.     static int a , s , s0 , sz_f;
  11.     static Set<Integer> F;
  12.     static Map<Pair<Integer , Character> , ArrayList<Integer>> f;
  13.     static Map<Pair<Integer , Integer> , ArrayList<Character>> rf;
  14.     static Set<Integer> S;
  15.  
  16.  
  17.     public static void main (String[] args) throws java.lang.Exception
  18.     {
  19.         Scanner sc = new Scanner(System.in);
  20.         a = sc.nextInt();
  21.         s = sc.nextInt();
  22.         S = new HashSet<Integer>();
  23.         for(int i = 0 ; i < s ; ++i)S.add(i);
  24.         s0 = sc.nextInt();
  25.         --s0;
  26.         sz_f = sc.nextInt();
  27.         F = new HashSet<Integer>();
  28.         for(int i = 0 ; i < sz_f ; ++i){
  29.             F.add(sc.nextInt() - 1);
  30.         }
  31.         f = new HashMap();
  32.         rf = new HashMap();
  33.         //int k = sc.nextInt();
  34.         //while(k-->0){
  35.         while(sc.hasNext()){
  36.             int u = sc.nextInt();
  37.             char ch = sc.next().charAt(0);
  38.             int v = sc.nextInt();
  39.             --u;
  40.             --v;
  41.             if(!f.containsKey(new Pair<Integer , Character>(u , ch))){
  42.                 f.put((new Pair<Integer , Character>(u , ch)), new ArrayList<Integer>());
  43.             }
  44.             if(!rf.containsKey(new Pair<Integer , Integer>(v , u))){
  45.                 rf.put((new Pair<Integer , Integer>(v , u)), new ArrayList<Character>());
  46.             }
  47.             ArrayList<Integer> tmp = f.get(new Pair<Integer , Character>(u , ch));
  48.             tmp.add(v);
  49.             f.put(new Pair<Integer , Character>(u , ch), tmp);
  50.             ArrayList<Character> tmp1 = rf.get(new Pair<Integer , Integer>(v , u));
  51.             tmp1.add(ch);
  52.             rf.put(new Pair<Integer , Integer>(v , u), tmp1);
  53.  
  54.         }
  55.  
  56.  
  57.         boolean used[] = new boolean[s];
  58.         Arrays.fill(used , false);
  59.         dfs1(s0 , used);
  60.         Drop(used);
  61.         Arrays.fill(used , false);
  62.         for(int v : F){
  63.             if(!used[v]){
  64.                 dfs2(v , used);
  65.             }
  66.         }
  67.         Drop(used);
  68.  
  69.         Map<Integer, Set<String>> out = new HashMap();
  70.         for(int u : S){
  71.             out.put(u , bfs(u));
  72.         }
  73.         DSU dsu = new DSU(s);
  74.         for(int u : S){
  75.             for(int v : S){
  76.                 if(dsu.find_set(u) != dsu.find_set(v)){
  77.                     if(equalSets(out.get(u) , out.get(v))){
  78.                         dsu.union_sets(u , v);
  79.                     }
  80.                 }
  81.             }
  82.         }
  83.         for(int i = 0 ; i < s ; ++i){
  84.             if(dsu.find_set(i) != i){
  85.                 merge_states(dsu.find_set(i) , i);
  86.             }
  87.         }
  88.         if(S.size() == 0 || !S.contains(s0)){
  89.             System.out.println("Empty automata");
  90.             return;
  91.         }
  92.         System.out.println(a);
  93.         System.out.println(S.size());
  94.         for(int i : S){
  95.             System.out.print(i + 1 + " ");
  96.         }
  97.         System.out.println();
  98.         System.out.println(s0 + 1);
  99.         System.out.println(F.size());
  100.         for(int i : F){
  101.             System.out.print(i + 1 + " ");
  102.         }
  103.         System.out.println();
  104.         for(Pair<Integer,Character> key : f.keySet()){
  105.             for(int to : f.get(key)){
  106.                 System.out.println((key.first() + 1) + " " + key.second() + " " + (to + 1));
  107.             }
  108.         }
  109.     }
  110.  
  111.     static void merge_states(int a , int b){
  112.         S.remove(b);
  113.         F.remove(b);
  114.  
  115.         for(char c = 'a' ; c <= 'a' + Main.a ; ++c){
  116.             f.remove(new Pair<Integer , Character>(b , c));
  117.         }
  118.         Set<Pair<Integer , Character>> update = new HashSet();
  119.         for(Pair<Integer , Integer> key : rf.keySet()){
  120.             if(key.first() == b){
  121.                 ArrayList<Character> tmp = rf.get(key);
  122.                 for(char ch : tmp) {
  123.                     update.add(new Pair<Integer, Character>(key.second(), ch));
  124.                 }
  125.             }
  126.         }
  127.         for (Pair<Integer , Character> key : update){
  128.             ArrayList<Integer> val = f.get(key);
  129.             if(val == null)continue;
  130.             if(!val.contains(a)){
  131.                 val.add(a);
  132.             }
  133.             val.remove((Object)b);
  134.             f.put(key , val);
  135.         }
  136.     }
  137.     static boolean equalSets(Set<String> a , Set<String> b){
  138.         if(a.size() != b.size())return false;
  139.         for(String s : a){
  140.             if(!b.contains(s)){
  141.                 return false;
  142.             }
  143.         }
  144.         return true;
  145.     }
  146.  
  147.     static void Drop(boolean used[]){
  148.         ArrayList<Pair<Integer,Integer>> rf_remove = new ArrayList();
  149.         for(int i = 0 ; i < s ; ++i){
  150.             if(!used[i]){
  151.                 S.remove(i);
  152.                 F.remove(i);
  153.                 for(ArrayList<Integer> al : f.values()){
  154.                     //al.remove(i);
  155.                     if(al == null)continue;
  156.                     al.remove((Object)i);
  157.                 }
  158.                 for(Pair<Integer,Integer> key : rf.keySet()){
  159.                     if(key.first().equals(i) || key.second().equals(i)){
  160.                         //rf.remove(key);
  161.                         rf_remove.add(key);
  162.                     }
  163.                 }
  164.                 for(char c = 'a' ; c < 'a' + a ; ++c){
  165.                     f.remove(new Pair<Integer , Character>(i , c));
  166.                 }
  167.             }
  168.         }
  169.         for (Pair<Integer,Integer> key : rf_remove){
  170.             rf.remove(key);
  171.         }
  172.     }
  173.  
  174.     static void dfs1(int cur , boolean used[]){
  175.         used[cur] = true;
  176.         for(char ch = 'a' ; ch < 'a' + a ; ++ch){
  177.             if(f.containsKey(new Pair<Integer , Character>(cur , ch))){
  178.                 ArrayList<Integer> tmp = f.get(new Pair<Integer , Character>(cur , ch));
  179.                 for(int v : tmp){
  180.                     if(!used[v]){
  181.                         dfs1(v , used);
  182.                     }
  183.                 }
  184.             }
  185.         }
  186.     }
  187.  
  188.     static  void dfs2(int cur , boolean used[]){
  189.         used[cur] = true;
  190.         for(int u : S){
  191.             if(!used[u]){
  192.                 if(rf.keySet().contains(new Pair<Integer, Integer>(cur , u))){
  193.                     dfs2(u , used);
  194.                 }
  195.             }
  196.         }
  197.     }
  198.  
  199.  
  200.  
  201.     static Set<String> bfs(int start){
  202.         Set<String> ans = new HashSet<String>();
  203.         Queue<Pair<Integer , String>> q = new PriorityQueue();
  204.         q.add(new Pair<Integer , String>(start , ""));
  205.         while(q.size() > 0){
  206.             Pair<Integer , String> cur = q.element();
  207.             q.remove();
  208.             if(cur.second().length() > Math.max(S.size() - 2 , 1))continue;
  209.             if(F.contains(cur.first())){
  210.                 ans.add(cur.second());
  211.             }
  212.             for(char ch = 'a' ; ch < 'a' + a ; ++ch){
  213.                 if(f.containsKey(new Pair<Integer , Character>(cur.first() , ch))){
  214.                     ArrayList<Integer> tmp = f.get(new Pair<Integer , Character>(cur.first() , ch));
  215.                     for(int v : tmp){
  216.                         if((cur.second() + ch).length() <= Math.max(S.size() - 2 , 1)){
  217.                             q.add(new Pair<Integer , String>(v , cur.second() + ch));
  218.                         }
  219.                     }
  220.                 }
  221.             }
  222.  
  223.         }
  224.         return ans;
  225.     }
  226.  
  227.  
  228. }
  229.  
  230. class DSU{
  231.     private int[] parent;
  232.     private int[] rank;
  233.  
  234.     public DSU(int n){
  235.         parent = new int[n];
  236.         rank = new int[n];
  237.         for(int i = 0 ; i < n ; ++i){
  238.             parent[i] = i;
  239.             rank[i] = 1;
  240.         }
  241.     }
  242.  
  243.     public int find_set(int v){
  244.         if(parent[v] == v){
  245.             return v;
  246.         }else{
  247.             parent[v] = find_set(parent[v]);
  248.         }
  249.         return parent[v];
  250.     }
  251.  
  252.     public void union_sets(int a , int b){
  253.         a = find_set(a);
  254.         b = find_set(b);
  255.         if(a != b){
  256.             if(rank[a] < rank[b]){
  257.                 int tmp = a;
  258.                 a = b;
  259.                 b = tmp;
  260.             }
  261.             parent[b] = a;
  262.             if(rank[a] == rank[b]){
  263.                 ++rank[a];
  264.             }
  265.         }
  266.     }
  267. }
  268.  
  269. class Pair<T1 extends Comparable<T1> , T2  extends Comparable<T2> > implements Comparable<Pair<T1,T2>>{
  270.     T1 x;
  271.     T2 y;
  272.     Pair(T1 _x , T2 _y){
  273.         x = _x;
  274.         y = _y;
  275.     }
  276.     T1 first(){
  277.         return x;
  278.     }
  279.     T2 second(){
  280.         return y;
  281.     }
  282.     public final Comparator<Pair<T1, T2>> KEY_COMPARATOR = new Comparator<Pair<T1, T2>>() {
  283.         public int compare(Pair<T1, T2> first, Pair<T1, T2> second) {
  284.             if(first.first().equals(second.first()))
  285.                 return first.second().compareTo(second.second());
  286.             return  first.first().compareTo(second.first());
  287.         }
  288.     };
  289.  
  290.     @Override
  291.     public int compareTo(Pair<T1,T2> other){
  292.         if(first().equals(other.first()))
  293.             return second().compareTo(other.second());
  294.         return  first().compareTo(other.first());
  295.     }
  296.     public boolean equals(Object other){
  297.         if (other instanceof Pair) {
  298.             Pair otherPair = (Pair) other;
  299.             return
  300.                     ((  this.x == otherPair.x ||
  301.                             ( this.x != null && otherPair.x != null &&
  302.                                     this.x.equals(otherPair.x))) &&
  303.                             (   this.y == otherPair.y ||
  304.                                     ( this.y != null && otherPair.y != null &&
  305.                                             this.y.equals(otherPair.y))) );
  306.         }
  307.         return false;
  308.     }
  309.  
  310.     public String toString(){
  311.         return "{" + x.toString() + " ; " + y.toString() + "}";
  312.     }
  313.  
  314.     public int hashCode(){
  315.         int hash = 31;
  316.         int res = 1;
  317.         res = hash * res + x.hashCode();
  318.         res = hash * res + y.hashCode();
  319.         return res;
  320.     }
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement