pojdijkstra+邻接表

题目:http://poj.org/problem?id=2387

题意:求N到1的最短路,即也可以是1到N.

易错点:输入是 t 然后 n 也就是说 ,先输入路径条数,再输入城市个数。

方法:直接dijkstra;我想试试再加上邻接表,结果写了半天。

原因是记熟了模板,忘记的基本原理。。。。。

而后又借鉴别人的代码,得到dijkstra+邻接表+优先队列;


dijkstra+邻接表

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
const int N=1e3+10;
const int inf=1e9;
struct road
{ 
    int v,w;
	road(int v,int w)
	:v(v),w(w){}	
}; 
vector<road>v[N];
int dis[N],vis[N],n,t,U,V,W;
void init()
{
	for(int i=0;i<n;++i)
	v[i].clear();
	for(int i=1;i<=n;++i)
	dis[i]=inf;
}
void input()
{
	for(int i=0;i<t;++i)
	{
		cin>>U>>V>>W;
		v[U].push_back(road(V,W));
		v[V].push_back(road(U,W));
	}
}
void dijkstra()
{
	memset(vis,0,sizeof(vis));
	for(int i=0;i<v[1].size();++i)
		{
		 // cout<<v[1][i].v<<' '<<v[1][i].w<<endl; 
		 if(dis[v[1][i].v]>v[1][i].w)
		  dis[v[1][i].v]=v[1][i].w;
		} 
	vis[1]=1;
	dis[1]=0;
	int u;
	for(int i=0;i<n-1;++i)
	{
		int mins=inf;
		for(int j=1;j<=n;++j)
		{
			if(!vis[j]&&dis[j]<mins)
			{
				//cout<<j<<' '<<dis[j]<<endl;
				mins=dis[j];
				u=j;
			}
		}

		vis[u]=1;
		for(int j=0;j<v[u].size();++j)
		{
			//if(dis[v[u][j].v]>mins+v[u][j].w) 1.
			//dis[v[u][j].v]=mins+v[u][j].w; 
			if(dis[v[u][j].v]>dis[u]+v[u][j].w)
			dis[v[u][j].v]=dis[u]+v[u][j].w;
		}
	}
}
void print()
{
	cout<<dis[n]<<endl;
}
int main()
{
	while(cin>>t>>n)
	{
		init();
		
		input();
		
		dijkstra();
		
		print();
	}
} 
/*
1.理解错误,更新路径最短长度时,应该用到达[u]的距离再到v[u][j].v的距离;
而不是mins到v[u][j].v的距离。 
2.选取一个点到另一个点的最短路径时,勿忘加上!vis标记,且认清要标记的下标。
3.思维定势。。。。 
*/


dijkstra+邻接表+优先队列

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf=1e9;
const int N=1e3+10;
int dis[N],n,t,U,V,W;
struct road
{
    int v,w;
    road();
	road(int v,int w)
	:v(v),w(w){}
    bool operator < (const road & a)const
	{return w>a.w;}
};
vector<road>v[N];
priority_queue<road>q;
void init()
{
	for(int i=1;i<=n;++i)
	v[i].clear();
	for(int i=1;i<=n;++i)
	dis[i]=inf;
	while(!q.empty())
	q.pop();
}
void input()
{
	for(int i=0;i<t;++i)
	{
		cin>>U>>V>>W;
		v[U].push_back(road(V,W));
		v[V].push_back(road(U,W)); 
	}
}
void dijkstra()
{
	dis[1]=0;
	q.push(road(1,0));
	while(!q.empty())
	{
		road ic=q.top();
		q.pop();
		for(int i=0;i<v[ic.v].size();++i)
		{
			if(dis[v[ic.v][i].v]>v[ic.v][i].w+ic.w)
			{
				dis[v[ic.v][i].v]=v[ic.v][i].w+ic.w;
				q.push(road(v[ic.v][i].v,dis[v[ic.v][i].v]));
			}
		}
	}
}
void print()
{
	cout<<dis[n]<<endl;
}
int main()
{
	while(cin>>t>>n)
	{
		init();
		
		input();
		
		dijkstra();
		
		print();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值