int dijkstra(const graph &g, int src, int forbidden, const vi &costTable, int limitation) { pq queue; queue.push(make_pair(0, src)); vi output(g.size()); fill(output.begin(), output.end(), INF); while (!queue.empty() && output[g.size()-1] == INF) { pii p = queue.top(); queue.pop(); int cost = p.first; int index = p.second; if (output[index] != INF) { continue; } output[index] = cost; for (int i = 0; i < g[index].size(); i++) { int nextIndex = g[index][i]; if (output[nextIndex] != INF) { continue; } if (index == src && nextIndex == forbidden) { continue; } if (cost+1+costTable[nextIndex] > limitation) { continue; } queue.push(make_pair(cost+1, nextIndex)); } } return output[g.size()-1]; }
vector<int> daiquistra(graph& g, int v){ vector<int> dist(g.size(), INT_MAX); vector<int> prev(g.size(), -1); dist[v] = 0; set<pair<int, int> > q; for(int i = 0; i<g.size(); i++){ q.insert(make_pair(dist[i], i)); } while(!q.empty()){ int u = q.begin()->second; int p = q.begin()->first; q.erase(q.begin()); if(dist[u] == INT_MAX) break; for(int i = 0; i<g[u].size(); i++){ int w = g[u][i].second; int alt = dist[u] + g[u][i].first; if(alt < dist[w]){ q.erase(make_pair(dist[w], w)); dist[w] = alt; prev[w] = u; q.insert(make_pair(dist[w], w)); } } } return prev; }
vector<ulong> bfs(graph g, ulong source_node) { vector<bool> v_bool_visited = vector<bool>(g.size() + 1, false); v_bool_visited[source_node] = true; vector<ulong> m_shortest_path = vector<ulong>(g.size() + 1, ULONG_MAX); m_shortest_path[source_node] = 0; queue<int> q; for (ulong i = 0; i < g[source_node].size(); i++) { q.push(g[source_node][i]); } while (q.size() > 0) { ulong node = q.front(); q.pop(); cout << "Processing node: " << node << endl; vector<ulong> v_neighbors = g[node]; for(ulong i = 0; i < v_neighbors.size(); i++) { if(!v_bool_visited[i]) { q.push(v_neighbors[i]); if(m_shortest_path[v_neighbors[i]] == ULONG_MAX) m_shortest_path[v_neighbors[i]] = m_shortest_path[node] + 1; } } v_bool_visited[node] = true; } return m_shortest_path; }
void dfs(graph &g){ int tempo = 0; vector<int> t(g.size()), d(g.size()), c(g.size(), branco), antec(g.size(), -1); for(int i = 0; i<g.size(); i++){ if(c[i] == branco) vdfs(g, i, t, d, c, tempo, antec); } }
bool seller_ant(const graph& gr, const int start, const int finish /*nobody cares about that*/, Ant::way& out_way) { size_t total_visited = 0, cnt_visited = 0; std::vector < int > visited(gr.size(), 0); const size_t operation_limit = std::min( static_cast<size_t>(gr.size() * std::pow(gr.size(), 3.0/2)), gr.get_number_of_edges() * 2 ) * 5; return comv_dfs(start, gr, static_cast<double>(GREEDY_NUM) / GREEDY_DENOM, static_cast<double>(SWEET_TOOTH_NUM) / SWEET_TOOTH_DENOM, total_visited, operation_limit , visited, cnt_visited, 0, out_way, static_cast<double>(RAND_NUM) / RAND_DENOM) == Comv_res::FOUND; }
int solve(const graph &g, int w) { vi costTable; for (int i = 0; i < g.size(); i++) { costTable.push_back(dijkstraStartFromRoomWithBrokenDoor(g, i, w)); } for (int i = 0; i < 2*g.size(); i++) { if (reachableWithLimitation(g, costTable, i)) { return i; } } return -1; }
vector<int> bfs(graph& g){ vector<int> dist(g.size(), INT_MAX); vector<int> c(g.size(), branco); vector<int> antec(g.size(), -1); for(int i = 0; i<g.size(); i++){ if(c[i] == branco){ vbfs(g, i, dist, c, antec); } } return antec; }
bool troiscoloriable(graph & g) { vector<int> coul(g.size(), -1); int i, j; for (i = 0; i < (int) g.size(); ++i) { ++coul[i]; if (coul[i] > 2) return false; // Limite de couleur atteinte for (j = 0; j < (int) g[i].size(); ++j) { if (coul[g[i][j]] == coul[i]) { --i; break; } // Backtrack } } return true; }
int costoUniforme() { int size = G.size(); p_queue pq; map<pair<int, char>, bool> visited; pq.push(ici(0, 0, start)); while(!pq.empty()) { ici state = pq.top(); pq.pop(); int u = state.second.second; char prevch = state.second.first; if(visited.find(make_pair(u, prevch)) != visited.end()) continue; if(u == end) return state.first; visited[make_pair(u, prevch)] = true; edges& adj = G[u]; for(int i = 0; i < adj.size(); i++) { int v = adj[i].first; char currch = adj[i].second.first; if(currch == prevch) continue; if(visited.find(make_pair(v, currch)) == visited.end()) { pq.push(ici(state.first + adj[i].second.second, currch, v)); } } } return INF; }
int dijkstra() { int size = G.size(); vector<int> dist(size, INF); vector<int> prev(size, -1); vector<bool> visited(size, false); vector<char> fromch(size, -1); dist[start] = 0; fromch[start] = 0; for(int i = 0; i < size; i++) { int idx = -1; for(int j = 0; j < size; j++) if(!visited[j]) { if(idx == -1 || dist[idx] > dist[j]) idx = j; } visited[idx] = true; char pch = fromch[idx]; edges& adj = G[idx]; D(pch); for(int j = 0; j < size; j++) { ici state = adj[j]; if(pch == state.second.first) continue; if(dist[idx]+state.second.second < dist[state.first]) { dist[state.first] = dist[idx] + state.second.second; prev[state.first] = idx; fromch[state.first] = state.second.first; } } } return dist[end]; }
void dijkstra (graph g, int u, int v){ priority_queue<int> fila; vector<int> visited; int element, cost, atual; visited.resize (g.size(), max); visited[u] = 0; fila.push (u); while (!fila.empty()){ atual = fila.top(); fila.pop(); for (int i=0; i<g[atual].size(); i++){ element = g[atual][i].first; cost = g[atual][i].second; if (visited[element] > visited[atual] + cost){ visited[element] = visited[atual] + cost; fila.push (element); } } } cout << visited[v]; }
int maximum_matching(const graph &g, vector<pair<int,int>> &matching) { int n = g.size(); vector<int> mu(n), phi(n), rho(n), scanned(n); rep(v,n) mu[v] = phi[v] = rho[v] = v; for(int x = -1;;) { if(x < 0) { for(x = 0; x < n && (scanned[x] || !EVEN(x)); ++x); if(x == n) break; } int y = -1; for(auto &e: g[x]) if(OUTER(e) || (EVEN(e) && rho[e] != rho[x])) y = e; if(y == -1) scanned[x] = true, x = -1; else if(OUTER(y)) phi[y] = x; else { vector<int> dx(n,-2), dy(n,-2); for(int k = 0, w = x; dx[w] < 0; w = k%2 ? mu[w] : phi[w]) dx[w] = k++; for(int k = 0, w = y; dy[w] < 0; w = k%2 ? mu[w] : phi[w]) dy[w] = k++; bool vertex_disjoint = true; rep(v,n) if(dx[v] >= 0 && dy[v] > 0) vertex_disjoint = false; if(vertex_disjoint) { rep(v,n) if(dx[v] % 2 or dy[v] % 2) mu[phi[v]] = v, mu[v] = phi[v]; mu[x] = y; mu[y] = x; x = -1; rep(v,n) phi[v] = rho[v] = v, scanned[v] = false; } else { int r = x , d = n; rep(v,n) if(dx[v] >= 0 && dy[v] >= 0 && rho[v] == v && d > dx[v]) d = dx[v], r = v; rep(v,n) if((dx[v] <= d && dx[v] % 2 && rho[phi[v]] != r) || (dy[v] <= d && dy[v] % 2 && rho[phi[v]] != r)) phi[phi[v]] = v; if(rho[x] != r) phi[x] = y; if(rho[y] != r) phi[y] = x; rep(v,n) if(dx[rho[v]] >= 0 || dy[rho[v]] >= 0) rho[v] = r; } } }
bool uncoloriable(graph & g) { int i; for (i = 0; i < (int) g.size(); ++i) { if (g[i].size() != 0) return false; } return true; }
bool is_eulerian(graph &adj){ int n = adj.size(); for(int v = 0; v < n; v++){ if(adj[v].size() % 2 == 1){ return false; } } return true; }
pair<predecessors, distances> dijkstra(const graph &g, int from) { predecessors ps(g.size(), -1); distances ds(g.size(), INT_MAX); ds[from] = 0; vector<bool> processed(g.size(), false); for(int i = 0; i < g.size(); i++) { int v = minDistance(ds, processed); processed[v] = true; for(edge e : g[v]) { if(ds[e.first] > ds[v] + e.second) { ds[e.first] = ds[v] + e.second; ps[e.first] = v; } } } return {ps, ds}; }
//Takes a Graph g (EdgeList!!!) with N nodes and computes the MST and Cost of it. Time Complexity: O(M*log(M)) //Requires UnionFind-Datastructure!!! pair<graph,ll> buildMST(int N, graph& g) { UnionFind uf(N); graph mst; ll mst_cost = 0; int M = g.size(); sort(g.begin(),g.end()); for(int i = 0; i < M; i++) { int u = g[i].second.first, v = g[i].second.second; if(uf.findSet(u) != uf.findSet(v)) { mst.push_back(g[i]); mst_cost += g[i].first; uf.unionSets(u,v); } } return make_pair(mst,mst_cost); }
int computeSCC(graph &G,vector<int> &SCC) { //--------- reverse Graph---------------- graph GR(G.size()); for(int i=0;i<G.size();i++) for(list<int>::iterator j=G[i].begin();j!=G[i].end();j++) GR[*j].push_back(i); //-------------------------------------- list<int> topologicallySortedList; topologicalSort(GR,topologicallySortedList); //-------------------------------------- SCC.resize(G.size(),-1); int SCCNumber=0; while(topologicallySortedList.size()) { if(SCC[topologicallySortedList.front()]==-1) computeSCCDFS(G,topologicallySortedList.front(),SCCNumber++,SCC); topologicallySortedList.pop_front(); } return SCCNumber; }
int main() { while(true) { //scanf("%d\n", &M); cin >> M; if(M == 0) break; //scanf("%s %s\n", name, dest); cin >> name >> dest; map<string, int> index; index[name] = start = index.size() - 1; index[dest] = end = index.size() - 1; D(G.size()); G.resize(2); for(int i = 0; i < M; i++) { //scanf("%s %s %s\n", name, dest, word); cin >> name >> dest >> word; if(index.find(name) == index.end()) { index[name] = index.size() - 1; G.resize(G.size()+1); } if(index.find(dest) == index.end()) { index[dest] = index.size() - 1; G.resize(G.size()+1); } int a = index[name], b = index[dest]; //D(a); D(b); G[a].push_back(ici(b, word[0], word.length())); G[b].push_back(ici(a, word[0], word.length())); //D(name); D(dest); D(word); } int ans = dijkstraHeap(); if(ans == INF) puts("impossivel"); else printf("%d\n", ans); G.clear(); } }
vector<long long> dijkstras(graph &G,int source) { vector<long long> distance(G.size(),INT_MAX); vector<bool> isused(G.size(),false); distance[source]=0; for(int i=0;i<G.size();i++) { //--extract min operation----- int minnode=getmin(distance,isused); isused[minnode]=true; //-------------------------- cout<<"MINNODE = "<<minnode<<"distance"<<distance[minnode]<<endl; for(list<pair<int,int> >::iterator i=G[minnode].begin();i!=G[minnode].end();i++) { if(distance[i->first]>distance[minnode]+i->second) distance[i->first]=distance[minnode]+i->second; } } return distance; }
bool deuxcoloriable(graph & g) { vector<int> coul(g.size(), -1); stack<int> s; int i, j, x, y; for (i = 0; i < (int) g.size(); ++i) { if (coul[i] != -1) continue; coul[i] = 0; s.push(i); while (not s.empty()) { x = s.top(); s.pop(); for (j = 0; j < (int) g[x].size(); ++j) { y = g[x][j]; if (coul[y] == coul[x]) return false; if (coul[y] != -1) continue; coul[y] = 1 - coul[x]; s.push(y); } } } return true; }
vector<ulong> dijkstra(graph g, ulong source_node) { // the heap heap nodes_heap; vector<bool> v_bool_visited = vector<bool>(g.size()); v_bool_visited[source_node] = true; for (ulong i = 0; i < g[source_node].size(); i++) { g[source_node][i].heap_value = g[source_node][i].value; nodes_heap.push(g[source_node][i]); } // initialize the map that will store the shortest paths. vector<ulong> m_shortest_path = vector<ulong>(g.size()); m_shortest_path.assign(g.size(), ULLONG_MAX); m_shortest_path[source_node] = 0; edge next_edge; while (nodes_heap.size() > 0) { next_edge = nodes_heap.top(); nodes_heap.pop(); if (v_bool_visited[next_edge.head] && v_bool_visited[next_edge.tail]) continue; m_shortest_path[next_edge.tail] = m_shortest_path[next_edge.head] + next_edge.value; for (ulong i = 0; i < g[next_edge.tail].size(); i++) { if (!v_bool_visited[g[next_edge.tail][i].tail]) { edge e = g[next_edge.tail][i]; e.heap_value = m_shortest_path[next_edge.tail] + e.value; nodes_heap.push(e); } } // mark node as visited v_bool_visited[next_edge.tail] = true; } return m_shortest_path; }
int graph::append_to(graph &g){ // returns the index of the first node inserted int offset = g.size(); for (unsigned int i = 0; i < adj_list.size(); ++i){ g.insert_node(); // cout<<i<<" "<<acceptance[i].first<<" "<<acceptance[i].second<<endl; if (acceptance[i].first) g.set_acceptance(i, acceptance[i].second); } for (unsigned int i = 0; i < adj_list.size(); ++i) for (unsigned int j = 0; j < adj_list[i].size(); ++j) g.only_edge(i+offset, adj_list[i][j].first+offset, adj_list[i][j].second); return offset ; }
int parcours(int depart, int arrivee) { vector<int> current, next; vector<bool> vu(g.size(), false); int i, j, d = 0; current.push_back(depart); while (!current.empty()) { i = current.back(); current.pop_back(); if (i == arrivee) break; for (j = 0; j < (int) g[i].size(); ++j) { if (vu[g[i][j]]) continue; vu[g[i][j]] = true; next.push_back(g[i][j]); } if (current.empty()) {swap(current, next); ++d;} } return d - 1; }
graph cutTree(const graph &g) { int n = g.size(); Matrix capacity(n, Array(n)), flow(n, Array(n)); rep(u,n) for(auto &e: g[u]) capacity[e.from][e.to] += e.w; vector<int> p(n), prev; vector<int> w(n); for (int s = 1; s < n; ++s) { int t = p[s]; // max-flow(s, t) rep(i,n) rep(j,n) flow[i][j] = 0; int total = 0; while (1) { queue<int> Q; Q.push(s); prev.assign(n, -1); prev[s] = s; while (!Q.empty() && prev[t] < 0) { int u = Q.front(); Q.pop(); for(auto &e: g[u]) if (prev[e.to] < 0 && RESIDUE(u, e.to) > 0) { prev[e.to] = u; Q.push(e.to); } } if (prev[t] < 0) goto esc; int inc = 1e9; for (int j = t; prev[j] != j; j = prev[j]) inc = min(inc, RESIDUE(prev[j], j)); for (int j = t; prev[j] != j; j = prev[j]) flow[prev[j]][j] += inc, flow[j][prev[j]] -= inc; total += inc; } esc:w[s] = total; // make tree rep(u, n) if (u != s && prev[u] != -1 && p[u] == t) p[u] = s; if (prev[p[t]] != -1) p[s] = p[t], p[t] = s, w[s] = w[t], w[t] = total; } graph T(n); // (s, p[s]) is a tree edge of weight w[s] rep(s, n) if (s != p[s]) { T[ s ].push_back( Edge(s, p[s], w[s]) ); T[p[s]].push_back( Edge(p[s], s, w[s]) ); } return T; }
int solve(int s, int t) { if(t<0) return INVALID; if(s==G.size()-1) return 0; else if(DP.find(make_pair(s,t))==DP.end()) { DP[make_pair(s,t)]=INVALID; int MIN=INVALID; for(list<road>::iterator i=G[s].begin();i!=G[s].end();i++) { if(i->d==s) continue; MIN=min(MIN,i->l+solve(i->d,t-i->t)); } DP[make_pair(s,t)]=min(INVALID,MIN); } return DP[make_pair(s,t)]; }
int dijkstraHeap() { int size = G.size(); vector<int> dist(size, INF); vector<int> prev(size, -1); map<char, bool> visited[size]; p_queue pq; dist[start] = 0; pq.push(ici(dist[start], 0, start)); while(!pq.empty()) { ici state = pq.top(); int u = state.second.second; D(u); char prevch = state.second.first; // depends on problem pq.pop(); if(visited[u].find(prevch) != visited[u].end()) continue; visited[u][prevch] = true; edges& adj = G[u]; for(int i = 0; i < adj.size(); i++) { if(adj[i].second.first == prevch) continue; // depends on problem int v = adj[i].first; D(v); int ndist = dist[u] + adj[i].second.second; // dist[u] + dist_between(u, v); if(ndist < dist[v]) { dist[v] = ndist; prev[v] = u; pq.push(ici(state.first+adj[i].second.second, adj[i].second.first, v)); } // D(dist[v]); } } return dist[end]; }
bool go_ant(const graph& gr, const int start, const int finish, Ant::way& out_way) { std::vector < bool > visited(gr.size(), false); return ant_dfs(start, gr, finish, out_way, visited, static_cast<double>(GREEDY_NUM) / GREEDY_DENOM, static_cast<double>(SWEET_TOOTH_NUM) / SWEET_TOOTH_NUM); }
// Return the number of vertices in g inline std::size_t count_vertices( graph const& g ) { return g.size(); }
maxflow(graph& G) : n(G.size()), G(G) {}
scc(const graph& G) : n(G.size()), G(G), cnt(0), num(n), low(n), in(n) { rep(i, n) if (num[i] == 0) dfs(i); }