Bellman-Ford算法实现--POJ-3259

// aiqiyi.cpp: 定义控制台应用程序的入口点。  
//  

#include "stdafx.h"  
using namespace std;

class Node
{
public:
	int index;
	int parent;
	vector<int> next;
	int dist;
	Node(int val_index, int par, vector<int> nex, int val_dist) :
		index(val_index), parent(par), next(nex), dist(val_dist) {}
};

int main()
{
	int Farm_Num;
	int r_data,pc = 0,farm_num_temp,sign = 0;//sign:0--read farm_num;1--read farm_strucutre;2--read farm_route;3--read farm--hole 
	vector<vector<int> > Farm_Structure;//[i][0]:node_num,[i][1]:route_num,[i][2]:hole_num
	vector<vector<Node*> >Farm_Node;//[i]:the node set of farm[i]
	vector<vector<vector<int> > >Route;//[i]:the route set of farm(graph)[i]
	vector<vector<vector<int> > >Hole;//[i]:the hole set of farm[i]
	vector<map<pair<int,int>,int> >Way;//[i]:the way set of farm[i]---in this set, each edge's weight is the minimal number of all edges appearing in route/hole set

	//get data from cin buffer
	while (cin >> r_data)
	{
		//to get the number of graphs
		if (!pc)
		{
			Farm_Num = r_data;
			farm_num_temp = Farm_Num;
			sign = 1;
		}
		else if(sign == 1)//read farm_structure
		{
			farm_num_temp--;
			vector<int>farm_str_temp;
			farm_str_temp.push_back(r_data);
			for (int f_i = 0; f_i < 2; ++f_i)
			{
				cin >> r_data;
				pc++;
				farm_str_temp.push_back(r_data);
			}
			Farm_Structure.push_back(farm_str_temp);
			if (farm_str_temp[1])//route set exists
				sign = 2;
			else
				sign = 3;
		}
		else if (sign == 2)//read route_set
		{
			vector<vector<int> >farm_rou_graph;
			vector<int>farm_rou_temp(3,0);
			farm_rou_temp[0] = r_data;
			for (int r_i = 0; r_i < (*(Farm_Structure.end() - 1))[1] * 3 - 1; ++r_i)
			{
				cin >> r_data;
				pc++;
				farm_rou_temp[(r_i + 1) % 3] = r_data;
				if (r_i % 3 == 1)
					farm_rou_graph.push_back(farm_rou_temp);
			}
			Route.push_back(farm_rou_graph);
			if ((*(Farm_Structure.end() - 1))[2])//hole_set exists
				sign = 3;
			else
				sign = 1;
		}
		else //sign == 3:read hole_set
		{
			vector<vector<int> >farm_hol_graph;
			vector<int>farm_hol_temp(3, 0);
			farm_hol_temp[0] = -r_data;
			for (int h_i = 0; h_i < (*(Farm_Structure.end() - 1))[2] * 3 - 1; ++h_i)
			{
				cin >> r_data;
				pc++;
				farm_hol_temp[(h_i + 1) % 3] = -r_data;
				if (h_i % 3 == 1)
					farm_hol_graph.push_back(farm_hol_temp);
			}
			Hole.push_back(farm_hol_graph);
			if (farm_num_temp)// begin to read data again
				sign = 1;
			else
				break;
		}

		pc++;
	}

	//modify Way set
	for (int g_i = 0; g_i < Farm_Num; ++g_i)
	{
		map<pair<int,int>, int> way_temp;
		for (int r_i = 0; r_i < Farm_Structure[g_i][1]; ++r_i)//bidirectional weight
		{
			auto f_sign = way_temp.find({ Route[g_i][r_i][0]-1,Route[g_i][r_i][1]-1 });
			if (f_sign == way_temp.end())//not exist
				way_temp[{ Route[g_i][r_i][0]-1, Route[g_i][r_i][1]-1 }] = Route[g_i][r_i][2];
			else
				way_temp[{ Route[g_i][r_i][0]-1, Route[g_i][r_i][1]-1 }] = min(Route[g_i][r_i][2], way_temp[{ Route[g_i][r_i][0]-1, Route[g_i][r_i][1]-1 }]);
			
			auto g_sign = way_temp.find({ Route[g_i][r_i][1]-1,Route[g_i][r_i][0]-1 });
			if (g_sign == way_temp.end())//already exist
				way_temp[{ Route[g_i][r_i][1]-1, Route[g_i][r_i][0]-1 }] = Route[g_i][r_i][2];
			else
				way_temp[{ Route[g_i][r_i][1]-1, Route[g_i][r_i][0]-1 }] = min(Route[g_i][r_i][2], way_temp[{ Route[g_i][r_i][1]-1, Route[g_i][r_i][0]-1 }]);
		}
		for (int h_i = 0; h_i < Farm_Structure[g_i][2]; ++h_i)
		{
			auto f_sign = way_temp.find({ -Hole[g_i][h_i][0]-1,-Hole[g_i][h_i][1]-1 });
			if (f_sign == way_temp.end())//already exist
				way_temp[{ -Hole[g_i][h_i][0]-1, -Hole[g_i][h_i][1]-1 }] = Hole[g_i][h_i][2];
			else
				way_temp[{ -Hole[g_i][h_i][0]-1, -Hole[g_i][h_i][1]-1 }] = min(Hole[g_i][h_i][2], way_temp[{ -Hole[g_i][h_i][0]-1, -Hole[g_i][h_i][1]-1 }]);
		}
		Way.push_back(way_temp);
	}

	//generate graph
	for (int G_i = 0; G_i < Farm_Num; ++G_i)
	{
		vector<Node*> Farm_Node_temp;
		for (int n_i = 0; n_i < Farm_Structure[G_i][0]; ++n_i)
		{
			Farm_Node_temp.push_back(new Node(n_i, -1, vector<int>(), INT_MAX));//note that the index of node starts at 0
		}
		for (auto R_i = Way[G_i].begin(); R_i != Way[G_i].end(); ++R_i)
		{
			((Farm_Node_temp[(R_i->first).first])->next).push_back((R_i->first).second);
		}
		Farm_Node.push_back(Farm_Node_temp);
	}

	//Bellman-Ford Algorithm
	for (int g_i = 0; g_i < Farm_Num; ++g_i)
	{
		Farm_Node[g_i][0]->dist = 0;
		for (int v_i = 0; v_i < Farm_Structure[g_i][0] - 1; ++v_i)
		{
			for (auto r_i = Way[g_i].begin(); r_i != Way[g_i].end(); ++r_i)
			{
				//relax edge r_i
				if (Farm_Node[g_i][(r_i->first).second]->dist > (Farm_Node[g_i][(r_i->first).first]->dist) + r_i->second)
				{
					Farm_Node[g_i][(r_i->first).second]->dist = (Farm_Node[g_i][(r_i->first).first]->dist) + r_i->second;
					Farm_Node[g_i][(r_i->first).second]->parent = (r_i->first).first;
				}
			}
		}

		int print_sign = 0;
		for (auto r_j = Way[g_i].begin(); r_j != Way[g_i].end(); ++r_j)
		{
			if (Farm_Node[g_i][(r_j->first).second]->dist > (Farm_Node[g_i][(r_j->first).first]->dist) + r_j->second)
			{
				print_sign = 1;
				break;
			}
		}
		if (print_sign)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}

	return 0;
}

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#include "targetver.h"

#include<algorithm>
#include<iostream>
#include<map>
#include<vector>
// TODO: 在此处引用程序需要的其他头文件

然而poj不支持map的高级一些的功能,所以编译一直无法通过…

然后修改了一下,结果超时了。。。

这是新版的:

#include"iostream"
using namespace std;
#define inf 1e10
int dist[1005];

struct edge
{
	int stat, endi, weig;
}Edge[5200];

int num_node, num_pos, num_neg;

bool bellman(int pc)
{
	bool flag;
	for (int i = 0; i < num_node - 1; i++)
	{
		flag = false;
		for (int j = 0; j < pc; j++)
		{
			if (dist[Edge[j].endi] > dist[Edge[j].stat] + Edge[j].weig)
			{
				dist[Edge[j].endi] = dist[Edge[j].stat] + Edge[j].weig;
				flag = true;
			}
		}
		if (!flag)
			break;
	}

	for (int i = 0; i < pc; i++)
	{
		if (dist[Edge[i].endi] > dist[Edge[i].stat] + Edge[i].weig)
			return true;
	}

	return false;
}

int main()
{
	int N;
	cin>>N;
	while (N--)
	{
		memset(dist, inf, sizeof(dist));
		cin >> num_node >> num_pos >> num_neg;
		int pc = 0;
		for (int i = 1; i <= num_pos; i++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			Edge[pc].stat = Edge[pc + 1].endi = u;
			Edge[pc].endi = Edge[pc + 1].stat = v;
			Edge[pc++].weig = w;
			Edge[pc++].weig = w;
		}

		for (int j = 1; j <= num_neg; j++)
		{
			int u, v, w;
			cin >> u >> v >> w;
			Edge[pc].stat = u;
			Edge[pc].endi = v;
			Edge[pc++].weig = -w;
		}

		if (bellman(pc))
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
} 

附上超时版本(个人认为更鲁棒啊):

// aiqiyi.cpp: 定义控制台应用程序的入口点。  
//  

#include "stdafx.h"  
using namespace std;
#define INT_MAX 1e10
class Node
{
public:
	int index;
	vector<int> next;
	int dist;
	Node(int val_index,vector<int> nex, int val_dist) :
		index(val_index), next(nex), dist(val_dist) {}
};

string convert(int n)
{
	string res = "";
	if (n == 0)
		return "0";
	while (n)
	{
		res += char(n % 10+'0');
		n /= 10;
	}
	return res;
}

string trans(int x, int y)
{
	return convert(x) + '+' + convert(y);
}

vector<int>TRANS(string s)
{
	vector<int>res(2, 0);
	int len = s.size(),sign = 0;
	for (int i = 0; i < len; ++i)
	{
		if (s[i] != '+')
		{
			res[sign] *= 10;
			res[sign] += s[i] - '0';
		}
		else
			sign++;
	}
	return res;
}

int main()
{
	int Farm_Num;
	int r_data,pc = 0,farm_num_temp,sign = 0; 
	vector<vector<int> > Farm_Structure; 
	vector<vector<Node*> >Farm_Node; 
	vector<vector<vector<int> > >Route; 
	vector<vector<vector<int> > >Hole; 
	vector<map<string,int> >Way; 
	while (cin >> r_data)
	{
		if (!pc)
		{
			Farm_Num = r_data;
			farm_num_temp = Farm_Num;
			sign = 1;
		}
		else if(sign == 1) 
		{
			farm_num_temp--;
			vector<int>farm_str_temp;
			farm_str_temp.push_back(r_data);
			for (int f_i = 0; f_i < 2; ++f_i)
			{
				cin >> r_data;
				pc++;
				farm_str_temp.push_back(r_data);
			}
			Farm_Structure.push_back(farm_str_temp);
			if (farm_str_temp[1])//route set exists
				sign = 2;
			else
				sign = 3;
		}
		else if (sign == 2)//read route_set
		{
			vector<vector<int> >farm_rou_graph;
			vector<int>farm_rou_temp(3,0);
			farm_rou_temp[0] = r_data;
			for (int r_i = 0; r_i < (*(Farm_Structure.end() - 1))[1] * 3 - 1; ++r_i)
			{
				cin >> r_data;
				pc++;
				farm_rou_temp[(r_i + 1) % 3] = r_data;
				if (r_i % 3 == 1)
					farm_rou_graph.push_back(farm_rou_temp);
			}
			Route.push_back(farm_rou_graph);
			if ((*(Farm_Structure.end() - 1))[2])//hole_set exists
				sign = 3;
			else
				sign = 1;
		}
		else //sign == 3:read hole_set
		{
			vector<vector<int> >farm_hol_graph;
			vector<int>farm_hol_temp(3, 0);
			farm_hol_temp[0] = -r_data;
			for (int h_i = 0; h_i < (*(Farm_Structure.end() - 1))[2] * 3 - 1; ++h_i)
			{
				cin >> r_data;
				pc++;
				farm_hol_temp[(h_i + 1) % 3] = -r_data;
				if (h_i % 3 == 1)
					farm_hol_graph.push_back(farm_hol_temp);
			}
			Hole.push_back(farm_hol_graph);
			if (farm_num_temp)// begin to read data again
				sign = 1;
			else
				break;
		}

		pc++;
	}

	//modify Way set
	for (int g_i = 0; g_i < Farm_Num; ++g_i)
	{
		map<string, int> way_temp;
		for (int r_i = 0; r_i < Farm_Structure[g_i][1]; ++r_i)//bidirectional weight
		{
			map<string,int>::iterator f_sign = way_temp.find(trans(Route[g_i][r_i][0]-1,Route[g_i][r_i][1]-1));
			if (f_sign == way_temp.end())//not exist
				way_temp[trans( Route[g_i][r_i][0]-1, Route[g_i][r_i][1]-1 )] = Route[g_i][r_i][2];
			else
				way_temp[trans( Route[g_i][r_i][0]-1, Route[g_i][r_i][1]-1 )] = min(Route[g_i][r_i][2], way_temp[trans( Route[g_i][r_i][0]-1, Route[g_i][r_i][1]-1 )]);

			map<string, int>::iterator g_sign = way_temp.find(trans( Route[g_i][r_i][1]-1,Route[g_i][r_i][0]-1 ));
			if (g_sign == way_temp.end())//already exist
				way_temp[trans( Route[g_i][r_i][1]-1, Route[g_i][r_i][0]-1 )] = Route[g_i][r_i][2];
			else
				way_temp[trans( Route[g_i][r_i][1]-1, Route[g_i][r_i][0]-1 )] = min(Route[g_i][r_i][2], way_temp[trans( Route[g_i][r_i][1]-1, Route[g_i][r_i][0]-1 )]);
		}
		for (int h_i = 0; h_i < Farm_Structure[g_i][2]; ++h_i)
		{
			map<string, int>::iterator f_sign = way_temp.find(trans( -Hole[g_i][h_i][0]-1,-Hole[g_i][h_i][1]-1 ));
			if (f_sign == way_temp.end())//already exist
				way_temp[trans( -Hole[g_i][h_i][0]-1, -Hole[g_i][h_i][1]-1 )] = Hole[g_i][h_i][2];
			else
				way_temp[trans( -Hole[g_i][h_i][0]-1, -Hole[g_i][h_i][1]-1 )] = min(Hole[g_i][h_i][2], way_temp[trans( -Hole[g_i][h_i][0]-1, -Hole[g_i][h_i][1]-1 )]);
		}
		Way.push_back(way_temp);
	}

	//generate graph
	for (int G_i = 0; G_i < Farm_Num; ++G_i)
	{
		vector<Node*> Farm_Node_temp;
		for (int n_i = 0; n_i < Farm_Structure[G_i][0]; ++n_i)
		{
			Farm_Node_temp.push_back(new Node(n_i, vector<int>(), INT_MAX));//note that the index of node starts at 0
		}
		for (map<string, int>::iterator R_i = Way[G_i].begin(); R_i != Way[G_i].end(); ++R_i)
		{
			vector<int> temp_trans = TRANS(R_i->first);
			((Farm_Node_temp[temp_trans[0]])->next).push_back(temp_trans[1]);
		}
		Farm_Node.push_back(Farm_Node_temp);
	}

	//Bellman-Ford Algorithm
	for (int g_i = 0; g_i < Farm_Num; ++g_i)
	{
		bool flag;
		Farm_Node[g_i][0]->dist = 0;
		for (int v_i = 0; v_i < Farm_Structure[g_i][0] - 1; ++v_i)
		{
			flag = false;
			for (map<string, int>::iterator r_i = Way[g_i].begin(); r_i != Way[g_i].end(); ++r_i)
			{
				vector<int> temp_t = TRANS(r_i->first);
				//relax edge r_i
				if (Farm_Node[g_i][temp_t[1]]->dist > (Farm_Node[g_i][temp_t[0]]->dist) + r_i->second)
				{
					Farm_Node[g_i][temp_t[1]]->dist = (Farm_Node[g_i][temp_t[0]]->dist) + r_i->second;
					flag = true;
				}
			}
			if (!flag)
				break;
		}

		for (map<string, int>::iterator r_j = Way[g_i].begin(); r_j != Way[g_i].end(); ++r_j)
		{
			vector<int> temp_t = TRANS(r_j->first);
			if (Farm_Node[g_i][temp_t[1]]->dist > (Farm_Node[g_i][temp_t[0]]->dist) + r_j->second)
			{
				flag = true;
				break;
			}
		}
		if (flag)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
}

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/georgeandgeorge/article/details/80487993
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞