POJ 3259 SPFA
这题让我英语太受打击了,题意难懂,读懂题意纸老虎。
算法:
1.题意本质就是判断是否存在负权回路。
2.SPFA,一个点入队大于等于N次,就说明它存在负权回路。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <queue> #include <iostream> using namespace std; #define MAXN 100100 struct Edge { int u, next, val; Edge() {} Edge( int v , int Next ,int Val): u(v),next(Next), val(Val) { } }edge[MAXN]; const int inf = 0x7f7f7f7f; int head[MAXN],dis[MAXN], visit[MAXN], size, hash[MAXN]; int N, M, W, T; struct node { int ID,dis; }; void init( ) { for( int i = 0; i <= N; i++) { head[i] = -1; visit[i] = 0; dis[i] = inf; hash[i] = 0; } size = 0; } void AddEdge( int u, int v, int val, int num) { edge[size] = Edge( v, head[u], val); head[u] = size++; if( !num ) { edge[size] = Edge( u, head[v], val); head[v] = size++; } } void SPFA( ) { queue<node>q; node p; p.ID = 1; p.dis = 0; q.push(p); dis[1] = 0; while( !q.empty( )) { p = q.front( ); q.pop(); int v = p.ID; int wx = dis[v]; visit[v] = 0; for( int e = head[v]; e != -1; e = edge[e].next) { int u = edge[e].u; int w = edge[e].val; if( dis[u] > wx + w ) { dis[u] = wx + w; if( !visit[u] ) { p.ID = u; p.dis = dis[u]; visit[u] = 1; q.push( p ); hash[u]++; } if( hash[u] >= N ) { puts("YES"); return ; } } } } puts("NO"); } int main( ) { int a, b, c; scanf("%d", &T); while(T--) { scanf("%d%d%d", &N, &M, &W); init( ); for( int i = 1; i <= M; i++) { scanf("%d%d%d", &a, &b, &c); AddEdge( a, b, c, 0); } for( int i = 1; i <= W; i++) { scanf("%d%d%d", &a, &b, &c); AddEdge( a, b, -c, 1); } SPFA( ); } return 0; }
posted on 2012-07-10 18:32 more think, more gains 阅读(269) 评论(0) 编辑 收藏 举报