程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> POJ 3268

POJ 3268

編輯:關於C++

題目大意:給出一個單向帶權圖和一個點s,求點u,u到s的最短路徑和s到u的最短路徑之和最大。


對於s到任意點的最短路,直接dijkstra可以求出。

對於任意點到s的最短路,如果將所有邊反向然後求一次最短路,容易證明,求出的s到任意點v的最短路s-->v就是原來沒有反向的圖的v-->s的最短路。

所以先求一次dijkstra,保存此次的結果,然後把所有的邊反向,權值不變,再求一次dijkstra,將兩次結果加起來,計算它們之中的最大值。


#include
#include
#include
#include
using namespace std;
const int maxn=1010;
const int INF=(1<<29);
struct edge
{
	int to;
	int dis;
};
struct edge2
{
	int from;
	int to;
	int dis;
};
struct heapnode
{
	int di;
	int num;
	bool operator< (const heapnode j) const
	{
		return di>j.di;
	}
};
edge2 e[100010];
int d[maxn];
int sum[maxn];
int use[maxn];
int n;
vector G[maxn];
void dijkstra(int s);
int main(void)
{
	int i,u,v,p,q,m,ans;
	edge ed;
	while(scanf("%d%d%d",&n,&m,&q)==3)
	{
		for(i=1;i<=n;i++)
		{
			G[i].clear();
		}
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&u,&v,&p);
			ed.to=v;
			ed.dis=p;
			G[u].push_back(ed);
			e[i].from=u;
			e[i].to=v;
			e[i].dis=p;
		}
		dijkstra(q);
		for(i=1;i<=n;i++)
		{
			sum[i]=d[i];
			G[i].clear();
		}
		for(i=1;i<=m;i++)
		{
			ed.to=e[i].from;
			ed.dis=e[i].dis;
			G[e[i].to].push_back(ed);
		}
		dijkstra(q);
		ans=0;
		for(i=1;i<=n;i++)
		{
			ans=d[i]+sum[i]>ans?d[i]+sum[i]:ans;
		}
		printf("%d\n",ans);
	}
	return 0;
}
void dijkstra(int s)
{
	int i,u,p;
	heapnode h;
	priority_queue heap;
	for(i=1;i<=n;i++)
	{
		d[i]=INF;
		use[i]=0;
	}
	h.di=0;
	h.num=s;
	d[s]=0;
	heap.push(h);
	while(heap.empty()==false)
	{
		h=heap.top();
		heap.pop();
		u=h.num;
		if(use[u]==0)
		{
			use[u]=1;
			p=G[u].size();
			for(i=0;i

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved