标签:
poj3114:题目链接
.题目大意:给出n个城市,m条送信的渠道,u v w代表u城市送信到v城市需要w小时。同时如果两个城市属于一个国家,那么送信时间为0,在一个国家中的条件是所有城市相互之间可以送信到达。
强连通找出连通块,那么每个连通块就是一个国家,缩点,重新建图,spfa找出要求的最短路径
#include <cstdio> #include <cstring> #include <stack> #include <queue> #include <algorithm> using namespace std ; #define INF 0x3f3f3f3f struct node{ int u , v , w ; int next ; }edge[500000] , tree[500000]; int head[510] , h_tree[510] , cnt ; int low[510] , dnf[510] , time ; int belong[510] , vis[510] , dis[510] , num ; queue <int> que ; stack <int> sta ; void init() { cnt = time = num = 0 ; memset(head,-1,sizeof(head)) ; memset(h_tree,-1,sizeof(head)) ; memset(low,0,sizeof(low)) ; memset(dnf,0,sizeof(dnf)) ; memset(belong,0,sizeof(belong)) ; memset(vis,0,sizeof(vis)) ; } void add(int u,int v,int w) { edge[cnt].u = u ; edge[cnt].v = v ; edge[cnt].w = w ; edge[cnt].next = head[u] ; head[u] = cnt++ ; } void add_tree(int u,int v,int w) { tree[cnt].u = u ; tree[cnt].v = v ; tree[cnt].w = w ; tree[cnt].next = h_tree[u] ; h_tree[u] = cnt++ ; } void tarjan(int u) { dnf[u] = low[u] = ++time ; vis[u] = 1 ; sta.push(u) ; int i , v ; for(i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; if( !dnf[v] ) { tarjan(v) ; low[u] = min(low[v],low[u]) ; } else if( vis[v] ) low[u] = min(low[u],dnf[v]) ; } if( low[u] == dnf[u] ) { ++num ; while( 1 ) { i = sta.top() ; sta.pop() ; vis[i] = 0 ; belong[i] = num ; if( i == u ) break ; } } } int spfa(int u,int s) { while( !que.empty() ) que.pop() ; memset(vis,0,sizeof(vis)) ; memset(dis,INF,sizeof(dis)) ; vis[u] = 1 ; dis[u] = 0 ; que.push(u) ; int i , v ; while( !que.empty() ) { u = que.front() ; que.pop() ; vis[u] = 0 ; for(i = h_tree[u] ; i != -1 ; i = tree[i].next) { v = tree[i].v ; if( dis[v] > dis[u] + tree[i].w ) { dis[v] = dis[u] + tree[i].w ; if( !vis[v] ) { vis[v] = 1 ; que.push(v) ; } } } } return dis[s] ; } int main() { int n , m , q ; int u , v , w , i , j ; while( scanf("%d %d", &n, &m) && n+m > 0 ) { init() ; while( m-- ) { scanf("%d %d %d", &u, &v, &w) ; add(u,v,w) ; } for(i = 1 ; i <= n ; i++) if( !dnf[i] ) tarjan(i) ; for(i = 1 , cnt = 0 ; i <= n ; i++) { for(j = head[i] ; j != -1 ; j = edge[j].next) { u = belong[ edge[j].u ] ; v = belong[ edge[j].v ] ; w = edge[j].w ; if( u != v ) add_tree(u,v,w) ; } } scanf("%d", &q) ; while( q-- ) { scanf("%d %d", &u, &v) ; u = belong[u] ; v = belong[v] ; w = spfa(u,v) ; if( w == INF ) printf("Nao e possivel entregar a carta\n") ; else printf("%d\n", w) ; } printf("\n") ; } return 0 ; }
poj3114--Countries in War(强连通缩点+spfa)
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/45770027