Nadesłany przez Rafał Pytko, 26 września 2009 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
sss.cpp:
//silnie spojne skladowe //Rafał Pytko //www.algorytm.org (c) 2009 #include <cstdio> #include <set> #include <list> using namespace std; const int max_n = 10000; list<int> gS[max_n]; // wyjscie: graf SSS int sss[max_n]; // wyjscie: numer SSS wierzcholka i int ns; // wyjscie: ilosc SSS int sssF[max_n],ttt; bool sssvis[max_n]; list<int> adj[max_n]; // wejscie: graf list<int> adjT[max_n]; // wejscie: graf transponowany int n; // wejscie: ilosc wierzcholkow void sss_dfs(int v) { sssvis[v] = 1; for(list<int>::iterator it=adj[v].begin(); it != adj[v].end(); ++it) if(!sssvis[*it]) sss_dfs(*it); sssF[ttt++] = v; } void sss_dfs2(int v) { sss[v] = ns; sssvis[v] = 1; for(list<int>::iterator it=adjT[v].begin(); it != adjT[v].end(); ++it) if(!sssvis[*it]) sss_dfs2(*it); } void compute_sss() { for(int i = 0; i < n; ++i) { sssvis[i] = 0; gS[i].clear(); } ttt=0; for(int i = 0; i < n; ++i) if(!sssvis[i]) sss_dfs(i); for(int i = 0; i < n; ++i) sssvis[i] = 0; ns = 0; for(int i = ttt-1; i >= 0; --i) if(!sssvis[sssF[i]]) { sss_dfs2(sssF[i]); ++ns; } } void create_sss_graph() { // tworzenie grafu silnie spójnych składowych set<pair<int,int> > W; for(int i = 0; i < n; ++i) for(list<int>::iterator it=adj[i].begin(); it != adj[i].end(); ++it) if(sss[i] != sss[*it]) { if(W.find(make_pair(sss[i],sss[*it])) == W.end()) { gS[sss[i]].push_back(sss[*it]); W.insert(make_pair(sss[i],sss[*it])); } } } void transpose_graph() { for(int i = 0; i < n; ++i) for(list<int>::iterator it = adj[i].begin(); it != adj[i].end(); ++it) adjT[*it].push_back(i); } int main() { n = 7; // liczba wierzcholkow // graf jako lista sasiadow adj[0].push_back(1); adj[1].push_back(2); adj[2].push_back(3); adj[3].push_back(1); adj[3].push_back(4); adj[3].push_back(6); adj[4].push_back(5); adj[5].push_back(4); adj[6].push_back(1); // obliczamy graf transponowany transpose_graph(); // obliczamy silnie spojne skladowe compute_sss(); printf("Liczba SSS: %d\n", ns); for(int i = 0; i < n; ++i) { printf("wierz: %d, skladowa: %d\n", i+1, sss[i]+1); } // wypisywanie skladowych for(int i = 0; i < ns; ++i) { printf("Skladowa %d: ", i+1); for(int v = 0; v < n; ++v) if(sss[v] == i) { printf("%d, ", v+1); } printf("\n"); } // tworzymy graf SSS create_sss_graph(); printf("\n\ngraf SSS (lista sasiadow)\n"); for(int i = 0; i < ns; ++i) { printf("%d: ", i+1); for(list<int>::iterator it = gS[i].begin(); it != gS[i].end(); ++it) printf("%d, ", *it + 1); printf("\n"); } }