zoukankan      html  css  js  c++  java
  • POJ 3259 Wormholes SPFA算法题解

    版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者同意不得转载。 https://blog.csdn.net/kenden23/article/details/37738183

    本题事实上也能够使用SPFA算法来求解的,只是就一个关键点,就是当某个顶点入列的次数超过全部顶点的总数的时候,就能够推断是有负环出现了。

    SPFA原来也是能够处理负环的。

    只是SPFA这样的处理负环的方法自然比一般的Bellman Ford算法要慢点了。

    #include <stdio.h>
    #include <string.h>
    #include <limits.h>
    
    const int MAX_N = 501;
    const int MAX_M = 2501;
    const int MAX_W = 201;
    
    struct Edge
    {
    	int src, des, wei, next;
    	//Edge(int s, int d, int w) : src(s), des(d), wei(w) {}
    };
    
    Edge edge[(MAX_M<<1)+MAX_W];
    int dist[MAX_N];
    int head[MAX_N];
    bool vis[MAX_N];
    int qu[MAX_N];
    int cnt[MAX_N];
    int totalEdges;
    
    inline void insertEdge(int src, int des, int wei)
    {
    	edge[totalEdges].src = src, edge[totalEdges].des = des;
    	edge[totalEdges].wei = wei; edge[totalEdges].next = head[src];
    	head[src] = totalEdges++;
    }
    
    int N, M, W, F;
    
    bool cycleSPFA()
    {
    	for (int i = 1; i <= N; i++) dist[i] = INT_MAX;
    	dist[1] = 0;
    
    	memset(vis, 0, sizeof(bool)*(N+1));
    	memset(cnt, 0, sizeof(int)*(N+1));
    	int top = 0, tail = 1;	//循环队列的头和尾下标
    	qu[top] = 1;
    	vis[1] = true;
    	cnt[1] = 1;
    	while (top < tail)
    	{
    		int u = qu[top%MAX_N];		//自己定义循环队列
    		top++;
    		vis[u] = false;
    
    		for (int e = head[u]; e ; e = edge[e].next)
    		{
    			int v = edge[e].des;
    			if (dist[u]+edge[e].wei < dist[v])
    			{
    				dist[v] = dist[u]+edge[e].wei;
    				if (!vis[v])
    				{
    					vis[v] = true;
    					qu[tail%MAX_N] = v;
    					tail++;
    					cnt[v]++;		//记录入列次数
    					if (cnt[v] >= N) return true;
    				}
    			}
    		}
    	}
    	return false;
    }
    
    int main()
    {
    	int src, des, wei;
    	scanf("%d", &F);
    	while (F--)
    	{
    		scanf("%d %d %d", &N, &M, &W);
    		memset(head, 0, sizeof(int) * (N+1));
    		totalEdges = 1;
    		for (int i = 0; i < M; i++)
    		{
    			scanf("%d %d %d", &src, &des, &wei);
    			insertEdge(src, des, wei);
    			insertEdge(des, src, wei);
    		}
    		for (int i = 0; i < W; i++)
    		{
    			scanf("%d %d %d", &src, &des, &wei);
    			insertEdge(src, des, -wei);
    		}
    		if (cycleSPFA()) puts("YES");
    		else puts("NO");
    	}
    	return 0;
    }


查看全文
  • 相关阅读:
    【java】关于泛型修饰符
    【java】使用lambda和函数接口Comparator
    【js】简单模拟JQuery原理
    【js】事件捕获与冒泡 (这可能是这个知识点 字最少,且讲的最清楚的教程)
    【js】实现 鼠标按下并未松开 事件
    【js】多维排序
    【JS】 初识JS原型
    【MyBatis】逆向工程
    【Struts】struts的DevMode模式
    Linux下gcc相关
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10956203.html
  • Copyright © 2011-2022 走看看