Advertisement
Guest User

Untitled

a guest
Apr 29th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.94 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define MAXVERTICES 2000
  5.  
  6. typedef int TVertice;
  7.  
  8. typedef int TAresta;
  9.  
  10. typedef struct {
  11.   TVertice Vertice;
  12.   TAresta Aresta;
  13. } TAdjacencia;
  14.  
  15. typedef TAdjacencia TItem;
  16.  
  17. typedef struct SCelula *TApontador;
  18.  
  19. typedef struct SCelula {
  20.   TItem Item;
  21.   TApontador Prox;
  22. } TCelula;
  23.  
  24. typedef struct {
  25.   TApontador Primeiro, Ultimo;
  26.   int Tamanho;
  27. } TLista;
  28.  
  29. /* Inicia as variaveis da lista */
  30. void TLista_Inicia(TLista *pLista)
  31. {
  32.   pLista->Primeiro = NULL;
  33.   pLista->Ultimo = pLista->Primeiro;
  34.   pLista->Tamanho = 0;
  35. }
  36.  
  37. /* Retorna se a lista esta vazia */
  38. int TLista_EhVazia(TLista *pLista)
  39. {
  40.   return (pLista->Primeiro == NULL);
  41. }
  42.  
  43. /* Retorna o tamanho da lista */
  44. int TLista_Tamanho(TLista *pLista)
  45. {
  46.   return (pLista->Tamanho);
  47. }
  48.  
  49. /* Insere um item na primeira posicao da lista */
  50. int TLista_InserePrimeiro(TLista *pLista, TItem x)
  51. {
  52.   TApontador pNovo;
  53.  
  54.   pNovo = (TApontador) malloc(sizeof(TCelula));
  55.   pNovo->Item = x;
  56.   pNovo->Prox = pLista->Primeiro;
  57.   if (TLista_EhVazia(pLista))
  58.     pLista->Ultimo = pNovo;
  59.   pLista->Primeiro = pNovo;
  60.   pLista->Tamanho++;
  61.   return 1;
  62. }
  63.  
  64. /* Insere um item na ultima posicao da lista */
  65. int TLista_InsereUltimo(TLista *pLista, TItem x)
  66. {
  67.   TApontador pNovo;
  68.  
  69.   pNovo = (TApontador) malloc(sizeof(TCelula));
  70.   pNovo->Item = x;
  71.   pNovo->Prox = NULL;
  72.  
  73.   if (TLista_EhVazia(pLista))
  74.     pLista->Primeiro = pNovo;
  75.   else
  76.     pLista->Ultimo->Prox = pNovo;
  77.   pLista->Ultimo = pNovo;
  78.   pLista->Tamanho++;
  79.   return 1;
  80. }
  81.  
  82. /* Insere um item na lista na posicao apontada por p */
  83. int TLista_Insere(TLista *pLista, TApontador p, TItem x)
  84. {
  85.   TApontador pAnterior, pNovo;
  86.  
  87.   if (p == pLista->Primeiro)
  88.     return TLista_InserePrimeiro(pLista, x);
  89.   else if (p == NULL)
  90.     return TLista_InsereUltimo(pLista, x);
  91.   else {
  92.     pAnterior = pLista->Primeiro;
  93.     while ((pAnterior != pLista->Ultimo) && (pAnterior->Prox != p))
  94.       pAnterior = pAnterior->Prox;
  95.     if (pAnterior == pLista->Ultimo)
  96.       return 0;
  97.  
  98.     pNovo = (TApontador) malloc(sizeof(TCelula));
  99.     pNovo->Item = x;
  100.     pNovo->Prox = pAnterior->Prox;
  101.     pAnterior->Prox = pNovo;
  102.     pLista->Tamanho++;
  103.     return 1;
  104.   }
  105. }
  106.  
  107. /* Retira o item da primeira posicao da lista */
  108. int TLista_RetiraPrimeiro(TLista *pLista, TItem *pX)
  109. {
  110.   TApontador pAux;
  111.  
  112.   if (TLista_EhVazia(pLista))
  113.     return 0;
  114.  
  115.   pAux = pLista->Primeiro;
  116.   pLista->Primeiro = pAux->Prox;
  117.   *pX = pAux->Item;
  118.   free(pAux);
  119.   pLista->Tamanho--;
  120.  
  121.   return 1;
  122. }
  123.  
  124. /* Retira o item da ultima posicao da lista */
  125. int TLista_RetiraUltimo(TLista *pLista, TItem *pX)
  126. {
  127.   TApontador pAnterior, pAux;
  128.  
  129.   pAnterior = pLista->Primeiro;
  130.   if (pAnterior == pLista->Ultimo)
  131.     return TLista_RetiraPrimeiro(pLista, pX);
  132.   else {    
  133.     while (pAnterior->Prox != pLista->Ultimo)
  134.       pAnterior = pAnterior->Prox;
  135.  
  136.     pAux = pLista->Ultimo;
  137.     pAnterior->Prox = NULL;
  138.     pLista->Ultimo = pAnterior;
  139.     *pX = pAux->Item;
  140.     free(pAux);
  141.     pLista->Tamanho--;
  142.  
  143.     return 1;
  144.   }
  145. }
  146.  
  147. /* Retira o item da lista da posicao apontada por p */
  148. int TLista_Retira(TLista *pLista, TApontador p, TItem *pX)
  149. {
  150.   TApontador pAnterior, pAux;
  151.  
  152.   if (p == pLista->Primeiro)
  153.     return TLista_RetiraPrimeiro(pLista, pX);
  154.   else if (p == pLista->Ultimo)
  155.     return TLista_RetiraUltimo(pLista, pX);
  156.   else {
  157.     pAnterior = pLista->Primeiro;
  158.     while ((pAnterior != pLista->Ultimo) && (pAnterior->Prox != p))
  159.       pAnterior = pAnterior->Prox;
  160.     if (pAnterior == pLista->Ultimo)
  161.       return 0;
  162.  
  163.     pAux = pAnterior->Prox;
  164.     pAnterior->Prox = pAux->Prox;
  165.     *pX = pAux->Item;
  166.     free(pAux);
  167.     pLista->Tamanho--;
  168.     return 1;
  169.   }
  170. }
  171.  
  172. /* Retorna um apontador para o p-esimo item da lista */
  173. TApontador TLista_Retorna(TLista *pLista, int p)
  174. {
  175.   TApontador q;
  176.   int pos;
  177.  
  178.   pos = 0;
  179.   q = pLista->Primeiro;
  180.   while ((q != NULL) && (pos != p)) {
  181.     q = q->Prox;
  182.     pos++;
  183.   }
  184.  
  185.   return q;
  186. }
  187.  
  188. typedef struct {
  189.   TLista Adj[MAXVERTICES];
  190.   int NVertices;
  191.   int NArestas;
  192. } TGrafo;
  193.  
  194. /* Inicia as variaveis do grafo */
  195. int TGrafo_Inicia(TGrafo *pGrafo, int NVertices)
  196. {
  197.   TVertice u;
  198.  
  199.   if (NVertices > MAXVERTICES) 
  200.     return 0;
  201.  
  202.   pGrafo->NVertices = NVertices;
  203.   pGrafo->NArestas  = 0;
  204.   for (u = 0; u < pGrafo->NVertices; u++)
  205.     TLista_Inicia(&pGrafo->Adj[u]);
  206.  
  207.   return 1;
  208. }
  209.  
  210. /* Retorna o numero de vertices do grafo */
  211. int TGrafo_NVertices(TGrafo *pGrafo)
  212. {
  213.   return (pGrafo->NVertices);
  214. }
  215.  
  216. /* Retorna o numero de arestas do grafo */
  217. int TGrafo_NArestas(TGrafo *pGrafo)
  218. {
  219.   return (pGrafo->NArestas);
  220. }
  221.  
  222. /* Retorna se existe a aresta (u, v) no grafo */
  223. int TGrafo_ExisteAresta(TGrafo *pGrafo, TVertice u, TVertice v)
  224. {
  225.   TAdjacencia Adj;
  226.   TLista ListaAdj;
  227.   int IncideAresta;
  228.  
  229.   IncideAresta = 0;  
  230.   TLista_Inicia(&ListaAdj);
  231.   while (TLista_RetiraPrimeiro(&pGrafo->Adj[u], &Adj)) {
  232.     TLista_InsereUltimo(&ListaAdj, Adj);
  233.     IncideAresta = (Adj.Vertice == v);
  234.     if (IncideAresta)
  235.       break;
  236.   }
  237.  
  238.   while (TLista_RetiraPrimeiro(&ListaAdj, &Adj))
  239.     TLista_InsereUltimo(&pGrafo->Adj[u], Adj);
  240.  
  241.   return (IncideAresta);
  242. }
  243.  
  244. /* Insere a aresta e incidente aos vertices u e v no grafo */
  245. int TGrafo_InsereAresta(TGrafo *pGrafo, TVertice u, TVertice v, TAresta e)
  246. {
  247.   TAdjacencia Adj;
  248.  
  249.   Adj.Vertice = v;
  250.   Adj.Aresta  = e;
  251.   if (TLista_InsereUltimo(&pGrafo->Adj[u], Adj)) {
  252.     pGrafo->NArestas++;
  253.     return 1;
  254.   }
  255.   else
  256.     return 0;
  257. }
  258.  
  259. /* Retira a aresta e incidente aos vertices u e v no grafo */
  260. int TGrafo_RetiraAresta(TGrafo *pGrafo, TVertice u, TVertice v, TAresta *pE)
  261. {
  262.   TLista ListaAdj;
  263.   TAdjacencia Adj;
  264.   int IncideAresta;
  265.  
  266.   IncideAresta = 0;
  267.   TLista_Inicia(&ListaAdj);
  268.   while (!IncideAresta && TLista_RetiraPrimeiro(&pGrafo->Adj[u], &Adj))
  269.     if (Adj.Vertice == v) {
  270.       *pE = Adj.Aresta;
  271.       pGrafo->NArestas--;
  272.       IncideAresta = 1;
  273.     }
  274.     else     
  275.       TLista_InsereUltimo(&ListaAdj, Adj);
  276.  
  277.   while (TLista_RetiraPrimeiro(&ListaAdj, &Adj))
  278.     TLista_InsereUltimo(&pGrafo->Adj[u], Adj);
  279.  
  280.   return IncideAresta;
  281. }
  282.  
  283. /* Retorna a lista de adjacentes do vertice u no grafo */
  284. TLista *TGrafo_ListaAdj(TGrafo *pGrafo, TVertice u)
  285. {
  286.   TLista *pLista, ListaAdj;
  287.   TAdjacencia Adj;
  288.  
  289.   pLista = (TLista *) malloc(sizeof(TLista));
  290.   TLista_Inicia(pLista);
  291.  
  292.   TLista_Inicia(&ListaAdj);
  293.   while (TLista_RetiraPrimeiro(&pGrafo->Adj[u], &Adj))
  294.     TLista_InsereUltimo(&ListaAdj, Adj);
  295.  
  296.   while (TLista_RetiraPrimeiro(&ListaAdj, &Adj)) {
  297.     TLista_InsereUltimo(&pGrafo->Adj[u], Adj);
  298.     TLista_InsereUltimo(pLista, Adj);
  299.   }
  300.  
  301.   return pLista;    
  302. }
  303.  
  304. #define NIL -1
  305. #define INF -1
  306.  
  307. typedef int TTempo;
  308.  
  309. typedef struct {
  310.   TVertice Pai;
  311.   TTempo   Ini;
  312.   TTempo   Fim;
  313. } TBPInfo;
  314.  
  315. /* Realiza uma busca em profundidade no grafo a partir de um vertice */
  316. void TGrafo_BPVRecursivo(TGrafo *pGrafo, TVertice u, TBPInfo *Info, TTempo *Tempo)
  317. {
  318.   TLista *ListaAdj;
  319.   TAdjacencia Adj;
  320.   TVertice v;
  321.  
  322.   Info[u].Ini = ++(*Tempo);
  323.   ListaAdj = TGrafo_ListaAdj(pGrafo, u);           
  324.   while (TLista_RetiraPrimeiro(ListaAdj, &Adj)) {
  325.     v = Adj.Vertice;
  326.     if (Info[v].Ini == 0) {
  327.       Info[v].Pai = u;
  328.       TGrafo_BPVRecursivo(pGrafo, v, Info, Tempo);
  329.     }
  330.   }
  331.   free(ListaAdj);          
  332.   Info[u].Fim = ++(*Tempo);
  333. }
  334.  
  335. /* Realiza uma busca em profundidade no grafo a partir de um vertice */
  336. TBPInfo *TGrafo_BuscaProfundidadeNoVertice(TGrafo *pGrafo, TVertice s)
  337. {
  338.   TBPInfo *Info;
  339.   TTempo Tempo;
  340.   TVertice u;
  341.  
  342.   Info = (TBPInfo *) malloc(TGrafo_NVertices(pGrafo) * sizeof(TBPInfo));
  343.   for (u = 0; u < TGrafo_NVertices(pGrafo); u++) {
  344.     Info[u].Pai = NIL;
  345.     Info[u].Ini = 0;
  346.     Info[u].Fim = INF;
  347.   }
  348.  
  349.   Tempo = 0;
  350.   TGrafo_BPVRecursivo(pGrafo, s, Info, &Tempo);
  351.  
  352.   return Info;
  353. }
  354.  
  355. /* Realiza uma busca em profundidade no grafo */
  356. TBPInfo *TGrafo_BuscaProfundidade(TGrafo *pGrafo)
  357. {
  358.   TBPInfo *Info;
  359.   TTempo Tempo;
  360.   TVertice u;
  361.  
  362.   Info = (TBPInfo *) malloc(TGrafo_NVertices(pGrafo) * sizeof(TBPInfo));
  363.   for (u = 0; u < TGrafo_NVertices(pGrafo); u++) {
  364.     Info[u].Pai = NIL;
  365.     Info[u].Ini = 0;
  366.     Info[u].Fim = INF;
  367.   }
  368.  
  369.   Tempo = 0;
  370.   for (u = 0; u < TGrafo_NVertices(pGrafo); u++)
  371.     if (Info[u].Ini == 0)
  372.       TGrafo_BPVRecursivo(pGrafo, u, Info, &Tempo);
  373.  
  374.   return Info;
  375. }
  376.  
  377. int main()
  378. {
  379.   TGrafo *pGrafo;
  380.   int i, p, N, M;
  381.   TVertice u, v;
  382.   TBPInfo *Info;
  383.   int EhConexo;
  384.  
  385.   scanf("%d %d", &N, &M);
  386.    
  387.   pGrafo = (TGrafo *) malloc(sizeof(TGrafo));
  388.   TGrafo_Inicia(pGrafo, N);
  389.  
  390.   for (i = 0; i < M; i++) {
  391.     scanf("%d %d %d", &u, &v, &p);
  392.     TGrafo_InsereAresta(pGrafo, u-1, v-1, 0);
  393.     if (p == 2)
  394.         TGrafo_InsereAresta(pGrafo, v-1, u-1, 0);
  395.   }
  396.  
  397.   EhConexo = 1;
  398.   for (u = 0; u < N && EhConexo; u++) {
  399.     Info = TGrafo_BuscaProfundidadeNoVertice(pGrafo, u);
  400.     for (v = 0; v < N && EhConexo; v++)
  401.       if ((u != v) && (Info[v].Pai == NIL))
  402.         EhConexo = 0;
  403.     free(Info);
  404.   }
  405.   printf("%d\n", EhConexo);
  406.  
  407.   return 1;
  408. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement