Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.27 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define asp ""
  4. #define aps ''
  5. #define one 1
  6. #define two 2
  7. #define dif !=
  8. typedef long long ll;
  9. const ll mod = 1e9 + 7;
  10. const int maxn = 1e5 + 6;
  11. typedef pair<int,int> ii;
  12. vector<vector<ii>> inp; // grafo bidirecional para ler entrada
  13. vector<vector<ii>> g; // grafo direcional que rodarei a DP
  14. vector<vector<int>> perm; // guarda todas as permutacoes
  15. ll dp[maxn][6];
  16.  
  17. int find_root(int n){
  18.  
  19.     int ret;
  20.     for(int i=0;i<n;i++){
  21.         if(inp[i].size() == one){
  22.             ret = i;
  23.             break;
  24.         }
  25.     }
  26.  
  27.     vector<bool> mark;
  28.     for(int i=0;i<n;i++) mark.push_back(false);
  29.     g.resize(n+3);
  30.  
  31.     queue<int> q;
  32.     q.push(ret);
  33.     while(q.empty() == false){ // criando um grafo direcional para facilitar a DP
  34.  
  35.         int p = q.front();
  36.         q.pop();
  37.  
  38.         mark[p] = true;
  39.  
  40.         for(int i=0;i<inp[p].size();i++){
  41.             int v = inp[p][i].first;
  42.             int c = inp[p][i].second;
  43.             if(mark[v] == false){
  44.                 //cout << "vertex-> "<< p << " " << v << endl;
  45.                 g[p].push_back({v,c});
  46.                 q.push(v);
  47.             }
  48.         }
  49.     }
  50.     mark.clear();
  51.     inp.clear();
  52.  
  53.     return ret;
  54. }
  55.  
  56. void preProcess(){
  57.  
  58.     vector<int> aux;
  59.     for(int i=one;i<=5;i++) aux.push_back(i); // gerando todas as permutacoes (so para auxiliar)
  60.  
  61.     do{
  62.         perm.push_back(aux);
  63.     }while(next_permutation(aux.begin(),aux.end()));
  64. }
  65.  
  66. // indica qual a proxima permutacao valida
  67. int prox_value(vector<int>& aux,int cont){
  68.  
  69.     cont++;
  70.     while(cont < perm.size()){
  71.         bool ok = true;
  72.         for(int i=0;i<5;i++){
  73.             if(aux[i] == -one || aux[i] == 0) continue;
  74.             if(aux[i] dif perm[cont][i]) ok = false;
  75.         }
  76.         if(ok) return cont;
  77.         cont++;
  78.     }
  79.  
  80.     return -one;
  81. }  
  82.  
  83. ll solve(int root,int color){
  84.  
  85.     vector<int> dl(5);
  86.     vector<int> tour;
  87.     map<vector<int>,bool> mapa;
  88.  
  89.     if(color dif -one)if(dp[root][color] dif -one) return dp[root][color];
  90.     if(g[root].size() == 0) return one;
  91.     if(g[root].size() > 4) return 0;
  92.  
  93.     /* montando o dl */
  94.     dl[0] = color;
  95.     for(int i=0;i<g[root].size();i++){
  96.         int c = g[root][i].second;
  97.         dl[i+one] = c;
  98.         tour.push_back(g[root][i].first);
  99.     }
  100.     for(int i=g[root].size()+one;i<5;i++) dl[i] = -one;
  101.  
  102.  
  103.     ll ret = 0;
  104.     int cont = 0;
  105.     vector<int> aux(5);
  106.     cont = prox_value(dl,-one);
  107.     while(cont dif -one){
  108.  
  109.         ll at = one;
  110.         for(int i=0;i<5;i++){
  111.             if(dl[i] == -one) aux[i] = 0;
  112.             else aux[i] = perm[cont][i];
  113.         }
  114.  
  115.         if(mapa.count(aux) == 0){
  116.  
  117.             for(int i=0;i<tour.size();i++){
  118.                 at = ((at%mod) * (solve(tour[i],perm[cont][i+one])%mod))%mod;
  119.             }
  120.             ret += at;
  121.             ret %= mod;
  122.  
  123.             mapa[aux] = true;
  124.         }
  125.         //cout << ret << endl;
  126.  
  127.         cont = prox_value(dl,cont);
  128.     }
  129.  
  130.     if(color dif -one)dp[root][color] = ret; // atualiza a dp
  131.  
  132.     return ret;
  133. }
  134.  
  135. void init(){
  136.  
  137.     for(int i=0;i<maxn;i++){
  138.         for(int j=0;j<6;j++){
  139.             dp[i][j] = -one;
  140.         }
  141.     }
  142. }
  143.  
  144. int main(){
  145.  
  146.     ios::sync_with_stdio(0);
  147.     cin.tie(0);
  148.  
  149.     init();
  150.     int n;
  151.     cin >> n;
  152.     inp.resize(n+3);
  153.     for(int i=one;i<n;i++){
  154.         int u,v,c;
  155.         cin >> u >> v >> c;
  156.         u--;
  157.         v--;
  158.         inp[u].push_back({v,c});
  159.         inp[v].push_back({u,c});
  160.     }
  161.     int root = find_root(n); // escolhe uma folha para ser o root da DP
  162.     preProcess(); // cria todas as permutacoes das cores
  163.  
  164.  
  165.     ll ans = solve(root,-one)%mod; // no a ser visitado, cor antes daquele no
  166.     // -one == a raiz nao possui cor antes
  167.     cout << ans << endl;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement