Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define asp ""
- #define aps ''
- #define one 1
- #define two 2
- #define dif !=
- typedef long long ll;
- const ll mod = 1e9 + 7;
- const int maxn = 1e5 + 6;
- typedef pair<int,int> ii;
- vector<vector<ii>> inp; // grafo bidirecional para ler entrada
- vector<vector<ii>> g; // grafo direcional que rodarei a DP
- vector<vector<int>> perm; // guarda todas as permutacoes
- ll dp[maxn][6];
- int find_root(int n){
- int ret;
- for(int i=0;i<n;i++){
- if(inp[i].size() == one){
- ret = i;
- break;
- }
- }
- vector<bool> mark;
- for(int i=0;i<n;i++) mark.push_back(false);
- g.resize(n+3);
- queue<int> q;
- q.push(ret);
- while(q.empty() == false){ // criando um grafo direcional para facilitar a DP
- int p = q.front();
- q.pop();
- mark[p] = true;
- for(int i=0;i<inp[p].size();i++){
- int v = inp[p][i].first;
- int c = inp[p][i].second;
- if(mark[v] == false){
- //cout << "vertex-> "<< p << " " << v << endl;
- g[p].push_back({v,c});
- q.push(v);
- }
- }
- }
- mark.clear();
- inp.clear();
- return ret;
- }
- void preProcess(){
- vector<int> aux;
- for(int i=one;i<=5;i++) aux.push_back(i); // gerando todas as permutacoes (so para auxiliar)
- do{
- perm.push_back(aux);
- }while(next_permutation(aux.begin(),aux.end()));
- }
- // indica qual a proxima permutacao valida
- int prox_value(vector<int>& aux,int cont){
- cont++;
- while(cont < perm.size()){
- bool ok = true;
- for(int i=0;i<5;i++){
- if(aux[i] == -one || aux[i] == 0) continue;
- if(aux[i] dif perm[cont][i]) ok = false;
- }
- if(ok) return cont;
- cont++;
- }
- return -one;
- }
- ll solve(int root,int color){
- vector<int> dl(5);
- vector<int> tour;
- map<vector<int>,bool> mapa;
- if(color dif -one)if(dp[root][color] dif -one) return dp[root][color];
- if(g[root].size() == 0) return one;
- if(g[root].size() > 4) return 0;
- /* montando o dl */
- dl[0] = color;
- for(int i=0;i<g[root].size();i++){
- int c = g[root][i].second;
- dl[i+one] = c;
- tour.push_back(g[root][i].first);
- }
- for(int i=g[root].size()+one;i<5;i++) dl[i] = -one;
- ll ret = 0;
- int cont = 0;
- vector<int> aux(5);
- cont = prox_value(dl,-one);
- while(cont dif -one){
- ll at = one;
- for(int i=0;i<5;i++){
- if(dl[i] == -one) aux[i] = 0;
- else aux[i] = perm[cont][i];
- }
- if(mapa.count(aux) == 0){
- for(int i=0;i<tour.size();i++){
- at = ((at%mod) * (solve(tour[i],perm[cont][i+one])%mod))%mod;
- }
- ret += at;
- ret %= mod;
- mapa[aux] = true;
- }
- //cout << ret << endl;
- cont = prox_value(dl,cont);
- }
- if(color dif -one)dp[root][color] = ret; // atualiza a dp
- return ret;
- }
- void init(){
- for(int i=0;i<maxn;i++){
- for(int j=0;j<6;j++){
- dp[i][j] = -one;
- }
- }
- }
- int main(){
- ios::sync_with_stdio(0);
- cin.tie(0);
- init();
- int n;
- cin >> n;
- inp.resize(n+3);
- for(int i=one;i<n;i++){
- int u,v,c;
- cin >> u >> v >> c;
- u--;
- v--;
- inp[u].push_back({v,c});
- inp[v].push_back({u,c});
- }
- int root = find_root(n); // escolhe uma folha para ser o root da DP
- preProcess(); // cria todas as permutacoes das cores
- ll ans = solve(root,-one)%mod; // no a ser visitado, cor antes daquele no
- // -one == a raiz nao possui cor antes
- cout << ans << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement