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;
    }
  • 相关阅读:
    20.11.16 leetcode406 leetcode中的排序写法
    20.11.15 leetcode402
    20.11.14 leetcode1122(自定义排序)
    polyline NOIP模拟 数论 规律
    alien NOIP模拟 位运算 数论
    跳石头 vijos1981 NOIP2015 D2T1 二分答案 模拟 贪心
    寻找道路 vijos1909 NOIP2014 D2T2 SPFA
    不死的LYM NOIP模拟 二分+状压DP
    死亡的颂唱者 NOIP模拟 贪心 DFS
    无线网络发射器选址 vijos 1908 NOIP2014 D2T1 模拟
  • 原文地址:https://www.cnblogs.com/rainydays/p/1948671.html
Copyright © 2011-2022 走看看