首页 > 代码库 > POJ 3114 Countries in War(强联通分量+Tarjan)
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 }
POJ 3114 Countries in War(强联通分量+Tarjan)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。