zoukankan      html  css  js  c++  java
  • poj3259

    错了好多次,原因有,path是双向的,开始没考虑到。边的数组应开到2500*2 + 200。图式不连通的,要把图的各个部分都覆盖到。

    本题用spfa算法,判断是否有负权回路。若松弛过程中存在某点的入队次数>=n,则说明有,否则没有。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    
    const int maxn = 6000, inf = 100000000;
    
    struct Edge
    {
    	int v, w, next;
    	Edge()
    	{
    	}
    	Edge(int vv, int ww, int nn) :
    		v(vv), w(ww), next(nn)
    	{
    	}
    } e[maxn];
    
    int map[maxn], n, m, w;
    int dist[maxn];
    bool vis[maxn];
    int times[maxn];
    int q[maxn];
    
    void init()
    {
    	memset(map, -1, sizeof(map));
    	memset(vis, 0, sizeof(vis));
    	memset(times, 0, sizeof(times));
    	scanf("%d%d%d", &n, &m, &w);
    	for (int i = 0; i < n; i++)
    		dist[i] = inf;
    	for (int i = 0; i < m; i++)
    	{
    		int a, b, x;
    		scanf("%d%d%d", &a, &b, &x);
    		a--;
    		b--;
    		e[i * 2] = Edge(b, x, map[a]);
    		map[a] = i * 2;
    		e[i * 2 + 1] = Edge(a, x, map[b]);
    		map[b] = i * 2 + 1;
    	}
    	for (int i = m * 2; i < m * 2 + w; i++)
    	{
    		int a, b, x;
    		scanf("%d%d%d", &a, &b, &x);
    		a--;
    		b--;
    		x = -x;
    		e[i] = Edge(b, x, map[a]);
    		map[a] = i;
    	}
    }
    
    bool relax(int u, Edge &e)
    {
    	if (dist[e.v] > dist[u] + e.w)
    	{
    		dist[e.v] = dist[u] + e.w;
    		return true;
    	}
    	return false;
    }
    
    bool spfa(int x)
    {
    	int front = 0;
    	int rear = 1;
    	q[front] = x;
    	dist[x] = 0;
    	vis[x] = true;
    	while (front != rear)
    	{
    		int temp = q[front++];
    		if (front == maxn)
    			front = 0;
    		vis[temp] = false;
    		for (int i = map[temp]; i != -1; i = e[i].next)
    		{
    			if (relax(temp, e[i]) && !vis[e[i].v])
    			{
    				q[rear++] = e[i].v;
    				times[e[i].v]++;
    				if (times[e[i].v] > n)
    					return true;
    				if (rear == maxn)
    					rear = 0;
    			}
    		}
    	}
    	return false;
    }
    
    int main()
    {
    	//freopen("D:\\t.txt", "r", stdin);
    	int t;
    	scanf("%d", &t);
    	while (t--)
    	{
    		init();
    		bool ok = false;
    		for (int i = 0; i < n; i++)
    		{
    			if (dist[i] == inf)
    			if (spfa(i))
    			{
    				ok = true;
    				break;
    			}
    		}
    		if (ok)
    			printf("YES\n");
    		else
    			printf("NO\n");
    	}
    	return 0;
    }
  • 相关阅读:
    Undergound Heaven [only_for_information]
    Essential Booklist of .Net Framework
    Thinkpad T4x 风扇转速档位控制
    Hot scene AGAIN!
    JavaScript使用技巧精萃
    今天项目中遇到的一个问题:判断新闻Id是否存在
    C++编译过程中"没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题"? 的彻底解决
    SQL操作全集
    关于UrlReferrer传值的几点注意
    在ASP.Net2.0中使用UrlRewritingNet实现链接重写(转)
  • 原文地址:https://www.cnblogs.com/rainydays/p/1948671.html
Copyright © 2011-2022 走看看