algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Silnie spójne składowe - Implementacja w C/C++
Ocena użytkownikóww: *****  / 14
SłabyŚwietny
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");
  }
}
Dodaj komentarz