//Mateusz Piórkowski #include <iostream> #include <vector> #include <map> #include <algorithm> #include <set> struct edge{ int n1,n2; }; struct rondo_path{ edge e1,e2,e3,e4; int cost; }; struct rondo_edge{ int target; int cost; }; void get_possible_paths(std::vector<rondo_edge>* ronda, int n, int node, std::vector<int>& path, std::set<rondo_path>& path_list, int cost){ path.push_back(node); //std::cout << "node:" << node << " n:" << n << " cost: " << cost << "\n"; //for(int i=0; i<path.size(); i++) std::cout << path[i] << " "; //std::cout << "\n"; if(n==0){ if(cost>0 && path[4]>=path[0]){ //path[4]>=path[0] prevents adding the same path but in reverse rondo_path to_add({ {path[0],path[1]}, {path[1],path[2]}, {path[2],path[3]}, {path[3],path[4]}, cost }); path_list.insert(to_add); } }else{ for(int i=0; i<ronda[node].size(); i++){ if(std::count(path.begin(), path.end(), ronda[node][i].target)==0){ //Can't go twice to the same node get_possible_paths(ronda, n-1, ronda[node][i].target, path, path_list, cost+ronda[node][i].cost); } } } path.pop_back(); //std::cout << "asd\n"; } bool paths_overlap(rondo_path a, rondo_path b){ //edge* edge_i for(edge* edge_i=&a.e1; edge_i<=&a.e4; edge_i++){ for(edge* edge_j=&b.e1; edge_j<=&b.e4; edge_j++){ int imax = std::max(edge_i->n1, edge_i->n2); int imin = std::min(edge_i->n1, edge_i->n2); int jmax = std::max(edge_j->n1, edge_j->n2); int jmin = std::min(edge_j->n1, edge_j->n2); if(imax==jmax && imin==jmin) return true; } } return false; } bool paths_overlap(std::set<rondo_path> &rondo_paths, rondo_path b){ for(rondo_path i : rondo_paths){ if(paths_overlap(i,b)) return true; } return false; } struct rondo_paths_compare { inline bool operator() (const rondo_path& a, const rondo_path& b) { return a.cost < b.cost; } }; inline bool operator!=(const edge& a, const edge& b) { if(a.n1!=b.n1) return 1; else if(a.n2!=b.n2) return 1; else 0; } inline bool operator<(const edge& a, const edge& b) { if(a.n1!=b.n1) return a.n1 < b.n1; else return a.n2 < b.n2; } inline bool operator<(const rondo_path& a, const rondo_path& b) { if(a.cost!=b.cost) return a.cost > b.cost; if(a.e1!=b.e1) return a.e1 < b.e1; if(a.e2!=b.e2) return a.e2 < b.e2; if(a.e3!=b.e3) return a.e3 < b.e3; return a.e4 < b.e4; //if(a.n4!=b.n4) return a.n4 < b.n4; } int solve(std::set<rondo_path>& rondo_paths, std::set<rondo_path>& paths_added, int cost, std::set<rondo_path>::iterator start_it){ int max_out=0; //for(rondo_path i : rondo_paths){ for(auto it=start_it; it!=rondo_paths.end(); ++it){ bool overlap = paths_overlap(paths_added, *it); if(!overlap){ paths_added.insert(*it); int out = solve(rondo_paths, paths_added, it->cost, it); paths_added.erase(*it); max_out = std::max(max_out, out); } } return cost+max_out; } int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int n; std::cin >> n; std::vector<rondo_edge>* ronda = new std::vector<rondo_edge>[n]; //std::map<rondo_path,int> rondo_paths; //std::vector<rondo_path> rondo_paths; std::set<rondo_path> rondo_paths; //Read ronda for(int i=0; i<n-1; i++){ int ui,vi,zi; std::cin >> ui >> vi >> zi; ronda[ui-1].push_back({vi-1,zi}); ronda[vi-1].push_back({ui-1,zi}); } //Print ronda #ifdef DEBUG for(int i=0; i<n; i++){ std::cout << i+1 << ": "; for(int j=0; j<ronda[i].size(); j++){ std::cout << ronda[i][j].target+1 << "(" << ronda[i][j].cost << ") "; } std::cout << "\n"; } #endif //Fill rondo_paths for(int i=0; i<n; i++){ std::vector<int> path; get_possible_paths(ronda, 4, i, path, rondo_paths, 0); } //std::sort(rondo_paths.begin(), rondo_paths.end(), rondo_paths_compare()); //Print rondo_paths std::set<rondo_path> paths_added; //int output=0; #ifdef DEBUG for(rondo_path i : rondo_paths){ std::cout << i.e1.n1+1<<"-"<<i.e1.n2+1<<"-"<<i.e2.n2+1<<"-"<<i.e3.n2+1<<"-"<<i.e4.n2+1<<" "<<"("<<i.cost<<")\n"; //bool overlap = paths_overlap(paths_added, i); //std::cout << "Overlap: " << overlap << "\n"; /*if(!overlap){ paths_added.insert(i); output+=i.cost; std::cout << "Added\n"; }*/ } #endif int output = solve(rondo_paths, paths_added, 0, rondo_paths.begin()); std::cout << output << "\n"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | //Mateusz Piórkowski #include <iostream> #include <vector> #include <map> #include <algorithm> #include <set> struct edge{ int n1,n2; }; struct rondo_path{ edge e1,e2,e3,e4; int cost; }; struct rondo_edge{ int target; int cost; }; void get_possible_paths(std::vector<rondo_edge>* ronda, int n, int node, std::vector<int>& path, std::set<rondo_path>& path_list, int cost){ path.push_back(node); //std::cout << "node:" << node << " n:" << n << " cost: " << cost << "\n"; //for(int i=0; i<path.size(); i++) std::cout << path[i] << " "; //std::cout << "\n"; if(n==0){ if(cost>0 && path[4]>=path[0]){ //path[4]>=path[0] prevents adding the same path but in reverse rondo_path to_add({ {path[0],path[1]}, {path[1],path[2]}, {path[2],path[3]}, {path[3],path[4]}, cost }); path_list.insert(to_add); } }else{ for(int i=0; i<ronda[node].size(); i++){ if(std::count(path.begin(), path.end(), ronda[node][i].target)==0){ //Can't go twice to the same node get_possible_paths(ronda, n-1, ronda[node][i].target, path, path_list, cost+ronda[node][i].cost); } } } path.pop_back(); //std::cout << "asd\n"; } bool paths_overlap(rondo_path a, rondo_path b){ //edge* edge_i for(edge* edge_i=&a.e1; edge_i<=&a.e4; edge_i++){ for(edge* edge_j=&b.e1; edge_j<=&b.e4; edge_j++){ int imax = std::max(edge_i->n1, edge_i->n2); int imin = std::min(edge_i->n1, edge_i->n2); int jmax = std::max(edge_j->n1, edge_j->n2); int jmin = std::min(edge_j->n1, edge_j->n2); if(imax==jmax && imin==jmin) return true; } } return false; } bool paths_overlap(std::set<rondo_path> &rondo_paths, rondo_path b){ for(rondo_path i : rondo_paths){ if(paths_overlap(i,b)) return true; } return false; } struct rondo_paths_compare { inline bool operator() (const rondo_path& a, const rondo_path& b) { return a.cost < b.cost; } }; inline bool operator!=(const edge& a, const edge& b) { if(a.n1!=b.n1) return 1; else if(a.n2!=b.n2) return 1; else 0; } inline bool operator<(const edge& a, const edge& b) { if(a.n1!=b.n1) return a.n1 < b.n1; else return a.n2 < b.n2; } inline bool operator<(const rondo_path& a, const rondo_path& b) { if(a.cost!=b.cost) return a.cost > b.cost; if(a.e1!=b.e1) return a.e1 < b.e1; if(a.e2!=b.e2) return a.e2 < b.e2; if(a.e3!=b.e3) return a.e3 < b.e3; return a.e4 < b.e4; //if(a.n4!=b.n4) return a.n4 < b.n4; } int solve(std::set<rondo_path>& rondo_paths, std::set<rondo_path>& paths_added, int cost, std::set<rondo_path>::iterator start_it){ int max_out=0; //for(rondo_path i : rondo_paths){ for(auto it=start_it; it!=rondo_paths.end(); ++it){ bool overlap = paths_overlap(paths_added, *it); if(!overlap){ paths_added.insert(*it); int out = solve(rondo_paths, paths_added, it->cost, it); paths_added.erase(*it); max_out = std::max(max_out, out); } } return cost+max_out; } int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int n; std::cin >> n; std::vector<rondo_edge>* ronda = new std::vector<rondo_edge>[n]; //std::map<rondo_path,int> rondo_paths; //std::vector<rondo_path> rondo_paths; std::set<rondo_path> rondo_paths; //Read ronda for(int i=0; i<n-1; i++){ int ui,vi,zi; std::cin >> ui >> vi >> zi; ronda[ui-1].push_back({vi-1,zi}); ronda[vi-1].push_back({ui-1,zi}); } //Print ronda #ifdef DEBUG for(int i=0; i<n; i++){ std::cout << i+1 << ": "; for(int j=0; j<ronda[i].size(); j++){ std::cout << ronda[i][j].target+1 << "(" << ronda[i][j].cost << ") "; } std::cout << "\n"; } #endif //Fill rondo_paths for(int i=0; i<n; i++){ std::vector<int> path; get_possible_paths(ronda, 4, i, path, rondo_paths, 0); } //std::sort(rondo_paths.begin(), rondo_paths.end(), rondo_paths_compare()); //Print rondo_paths std::set<rondo_path> paths_added; //int output=0; #ifdef DEBUG for(rondo_path i : rondo_paths){ std::cout << i.e1.n1+1<<"-"<<i.e1.n2+1<<"-"<<i.e2.n2+1<<"-"<<i.e3.n2+1<<"-"<<i.e4.n2+1<<" "<<"("<<i.cost<<")\n"; //bool overlap = paths_overlap(paths_added, i); //std::cout << "Overlap: " << overlap << "\n"; /*if(!overlap){ paths_added.insert(i); output+=i.cost; std::cout << "Added\n"; }*/ } #endif int output = solve(rondo_paths, paths_added, 0, rondo_paths.begin()); std::cout << output << "\n"; } |