poj3259 Wormholes(spfa判负环)
题意:给m条路(S,E,T)代表点S、E之间双向边权重为T,紧接着给W个虫洞(S,E,T)代表S到E的有向边可以回到T秒前即权重为-T,问能不能通过虫洞看到看到初始的自己,即能不能回到初始点所在的时间点之前,即求是否存在负环。
代码细节就不多赘述了,spfa
#include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int maxn = 500 + 5; const int maxm = 3000 + 5; const int inf = 0x3f3f3f3f; int n, m, f, t, dis[maxn], inq[maxn]; int head[maxn], tot; bool vis[maxn]; struct edge{ int to, w, next; } ed[maxm*2]; inline void add( int u, int v, int w ){ ed[tot].to = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot ++; } inline bool spfa(){ queue<int> q; memset( vis, 0, sizeof(vis) ); memset( inq, 0, sizeof(inq) ); memset( dis, inf, sizeof(dis) ); dis[1] = 0; vis[1] = 1; q.push(1); while( !q.empty() ){ int u = q.front(); q.pop(); vis[u] = 0; if( ++inq[u]>=n ) return 1; for( int i=head[u]; i!=-1; i=ed[i].next ){ int v = ed[i].to; if( dis[v]>dis[u]+ed[i].w ){ dis[v] = dis[u]+ed[i].w; if( !vis[v] ){ vis[v] = 1; q.push(v); } } } } return 0; } int main(){ // freopen("in.txt", "r", stdin); cin >> f; while( f-- ){ memset( head, -1, sizeof(head) ); tot = 0; cin >> n >> m >> t; for( int i=0; i<m; i++ ){ int u, v, w; cin >> u >> v >> w; add( u, v, w ); add( v, u, w ); } for( int i=0; i<t; i++ ){ int u, v, w; cin >> u >> v >> w; add( u, v, -w ); } if( spfa() ) puts("YES"); else puts("NO"); } return 0; }