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;
}

猜你喜欢

转载自www.cnblogs.com/WAautomaton/p/10947190.html