POJ 3114 Countries in War(强联通分量+Tarjan)

题目链接

题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0.

思路 :强连通分量缩点之后,求最短路。以前写过,总感觉记忆不深,这次自己敲完再写了一遍。

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <iostream>

  4 #include <vector>

  5 #include <stack>

  6 #include <queue>

  7 #include <algorithm>

  8 #define maxn 505

  9 using namespace std ;

 10 

 11 struct node

 12 {

 13     int u,v,w,next ;

 14 } edge[maxn*maxn];

 15 int p[maxn][maxn];

 16 int dfn[maxn],low[maxn],head[maxn] ,vis[maxn],dis[maxn],belong[maxn];

 17 int timee,cnt ,cntt,n,m;

 18 stack<int>stk ;

 19 

 20 void Init()

 21 {

 22     timee = 0 ;

 23     cnt = cntt = 0 ;

 24     memset(dfn,0,sizeof(dfn)) ;

 25     memset(low,0,sizeof(low)) ;

 26     memset(dis,0,sizeof(dis)) ;

 27     memset(head,-1,sizeof(head)) ;

 28     memset(vis,0,sizeof(vis)) ;

 29     memset(p,0x3f,sizeof(p)) ;

 30 }

 31 void addedge(int u,int v,int w)

 32 {

 33     edge[cnt].u = u ;

 34     edge[cnt].v = v ;

 35     edge[cnt].w = w ;

 36     edge[cnt].next = head[u] ;

 37     head[u] = cnt++ ;

 38 }

 39 void tarjan(int u)

 40 {

 41     //cout<<u<<endl;

 42     int v ;

 43     vis[u] = 1 ;

 44     dfn[u] = low[u] = ++ timee ;

 45     stk.push(u) ;

 46     for(int i = head[u] ; i != -1 ; i = edge[i].next)

 47     {

 48         v = edge[i].v ;

 49         if(!dfn[v])

 50         {

 51             //printf("v = %d\n",v) ;

 52             tarjan(v) ;

 53             low[u] = min(low[v],low[u]) ;

 54         }

 55         else if(vis[v])

 56             low[u] = min(low[u],dfn[v]) ;

 57     }

 58     if(low[u] == dfn[u])

 59     {

 60         cntt ++ ;

 61         do

 62         {

 63             v = stk.top() ;

 64             stk.pop() ;

 65             vis[v] = 0 ;

 66             belong [v] = cntt ;

 67          //   puts("1") ;

 68         }

 69         while(v != u) ;

 70     }

 71 }

 72 void SPFA(int u,int v)

 73 {

 74     queue<int>Q ;

 75     for(int i = 1 ; i <= cntt ; i++)

 76     {

 77         dis[i] = 999999999 ;

 78         vis[i] = 0 ;

 79     }

 80     dis[u] = 0;

 81     vis[u] = 1;

 82     Q.push(u) ;

 83     while(!Q.empty())

 84     {

 85         int s = Q.front() ;

 86         Q.pop() ;

 87         vis[s] = 0 ;

 88         for(int i = 1 ; i <= n ; i ++ )

 89         {

 90             if(p[s][i] != 999999999)

 91             {

 92                 if(dis[i] > dis[s] + p[s][i])

 93                 {

 94                     dis[i] = dis[s] + p[s][i] ;

 95                     if(!vis[i])

 96                     {

 97                         Q.push(i) ;

 98                         vis[i] = 1 ;

 99                     }

100                 }

101             }

102         }

103     }

104     if(dis[v] != 999999999)

105         printf("%d\n",dis[v]) ;

106     else printf("Nao e possivel entregar a carta\n") ;

107 }

108 void rebuild()

109 {

110     for(int i = 1 ; i <= n ; i++)

111     {

112         for(int j = head[i] ; j != -1 ; j = edge[j].next)

113         {

114          //   int s = edge[i].v ;

115             int v = belong[edge[j].v] ;

116             int u = belong[edge[j].u] ;

117             if(u != v)

118                 p[u][v] = min(p[u][v],edge[j].w) ;

119         }

120     }

121     for(int i = 1 ; i <= cntt ; i++)

122         p[i][i] = 0 ;

123 }

124 int main()

125 {

126     int x,y,h,k;

127     while(~scanf("%d %d",&n,&m))

128     {

129         if(n == 0 && m == 0) break ;

130         Init() ;

131         for(int i = 0 ; i < m ; i++)

132         {

133             scanf("%d %d %d",&x,&y,&h) ;

134             addedge(x,y,h) ;

135         }

136         for(int i = 1 ; i <= n ; i++)

137         {

138             if(!dfn[i])

139                 tarjan(i) ;

140         }

141        // cout<<"s"<<endl;

142         rebuild() ;

143        // cout<<"s"<<endl;

144         scanf("%d",&k) ;

145         for(int i = 0 ; i < k ; i++)

146         {

147             //cout<<i<<endl;

148             scanf("%d %d",&x,&y) ;

149             SPFA(belong[x],belong[y]) ;

150         }

151         printf("\n") ;

152     }

153     return 0 ;

154 }
View Code

 

你可能感兴趣的:(count)