POJ3259 - Wormholes

本文介绍了一种使用Bellman-Ford算法检测图中是否存在负权回路的方法。通过构建图的数据结构并实现算法迭代更新顶点的最短路径成本,最终通过节点深度判断是否存在长度超过顶点数的路径,以此来确定是否存在负权环。
摘要由CSDN通过智能技术生成

bellman-ford算法判断环。


//Memory Time
//1260K	360MS	//不添加delete 
//488K	985MS   //添加delete之后 

#include<iostream>
#include<queue>
using namespace std;

struct edge{
	edge* next;
	int dst;
	int cost;
};

struct vextex{
	int cost;
	int deep;
	bool isAddInQueue;
};

vextex	vex[1000];
edge*	eg[1000];

int main()
{
	int N;
	cin >> N;
	for(int j = 0; j < N; j++)
	{
		int vNum, posCost, negCost;
		cin >> vNum >> posCost >> negCost;
		for(int i = 1; i <= vNum; i++)
		{
			eg[i]	= NULL;
			vex[i].cost = 2000000000;
			vex[i].deep = 0;
			vex[i].isAddInQueue = false;
		}
		for(int i = 0; i < posCost; i++)
		{
			int src,dst,cost;
			cin>>src>>dst>>cost;
			edge* e = new edge;
			e->cost = cost;
			e->dst  = dst;
			e->next = eg[src];
			eg[src] = e;
			
			e = new edge;
			e->cost = cost;
			e->dst  = src;
			e->next = eg[dst];
			eg[dst] = e;
		}
		for(int i = 0; i < negCost; i++)
		{
			int src,dst,cost;
			cin>>src>>dst>>cost;
			edge* e = new edge;
			e->cost = -cost;
			e->dst  = dst;
			e->next = eg[src];
			eg[src] = e;
		}
		
		vex[1].cost = 0;
		vex[1].deep = 1;
		vex[1].isAddInQueue = true;
		
		int maxDeep = 0;
		queue<int> que;
		que.push(1);
		while(!que.empty())
		{
			int tempSrc = que.front();
			vex[tempSrc].isAddInQueue = false;
			que.pop();
			edge* e = eg[tempSrc];
			while(e != NULL)
			{
				int tempDst = e->dst;
				int tempCost = vex[tempSrc].cost + e->cost;
				if(tempCost < vex[tempDst].cost)
				{
					vex[tempDst].cost = tempCost;
					vex[tempDst].deep = vex[tempSrc].deep+1;
					if(vex[tempDst].deep > maxDeep)
						maxDeep = vex[tempDst].deep;
					if(vex[tempDst].isAddInQueue == false)
					{
						vex[tempDst].isAddInQueue = true;
						que.push(tempDst);	
					}
				}
				e = e->next;
			}
			if(maxDeep > vNum)
				break;
		}
		
//		for(int i = 1; i <= vNum; i++)
//		{
//			edge* e = eg[i];
//			edge*tempE;
//			while(e != NULL)
//			{
//				tempE = e;
//				e = e->next;
//				delete tempE;
//			}
//		}
		
		if(maxDeep > vNum)
			cout << "YES" <<endl;
		else
			cout << "NO" <<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值