热浪(图论)

【问题描述】

德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他们的德克萨斯长角牛吃起来 不错,可是他们并不是很擅长生產富含奶油的乳製品。Farmer John 此时以先天下之忧而忧, 后天下之乐而乐的精神,身先士卒地承担起向德克萨斯运送大量的营养冰凉的牛奶的重任, 以减轻德克萨斯人忍受酷暑的痛苦。
FJ 已经研究过可以把牛奶从威斯康星运送到德克萨斯州的路线。这些路线包括起始点 和终点先一共经过 T (1 <= T <= 2,500)个城镇,方便地标号為 1 到 T。除了起点和终点外的 每个城镇由两条双向道路连向至少两个其它的城镇。每条道路有一个通过费用(包括油费, 过路费等等)。
给定一个地图,包含 C (1 <= C <= 6,200)条直接连接 2 个城镇的道路。每条道路由道路 的起点 Rs,终点 Re (1 <= Rs <= T; 1 <= Re <= T),和花费(1 <= Ci <= 1,000)组成。求从起始 的城镇 Ts (1 <= Ts <= T)到终点的城镇 Te(1 <= Te <= T)小的总费用。

【输入格式】

第一行: 4 个由空格隔开的整数: T, C, Ts, Te

【输出格式】

一个单独的整数表示从 Ts 到 Te 的小总费用。数据保证至少存在一条道路。

【输入输出样例】

input

7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

output

7

【样例说明】 
5->6->1->4 (3 + 1 + 3)

时间限制:1s
空间限制:128MB

题解:

dijkstra做法

#include<bits/stdc++.h>
using namespace std;
typedef struct node
{
	int v,w;
	bool operator < (const struct node & t)const
	{
		return w>t.w;
	}
}NODE,*PNODE;
vector<NODE> arr[2501];
NODE t,t1;
int visited[2501],dist[2501],s,e;
priority_queue<NODE> pq;
void dijkstra(int index)
{
	int i;
	t.v=index;
	t.w=0;
	pq.push(t);
	while(!pq.empty())
	{
		t=pq.top();
		pq.pop();
		if(visited[t.v])
			continue;
		dist[t.v]=t.w;
		visited[t.v]=1;
		if(t.v==e)
			return ;
		for(i=0;i<arr[t.v].size();i++)
		{
			if(visited[arr[t.v][i].v])
				continue;
			t1.v=arr[t.v][i].v;
			t1.w=dist[t.v]+arr[t.v][i].w;
			pq.push(t1);
		}
	}
}
int main()
{
	int n,m,i;
	scanf("%d %d %d %d",&n,&m,&s,&e);
	for(i=1;i<=m;i++)
	{
		int a,b,c;
		scanf("%d %d %d",&a,&b,&c);
		t.v=b,t.w=c;
		arr[a].push_back(t);
		t.v=a,t.w=c;
		arr[b].push_back(t);
	}
	dijkstra(s);
	printf("%d",dist[e]);
	return 0;
}

SPFA做法

#include<bits/stdc++.h>
using namespace std;
int head[2501],nxt[12400],to[12400],weight[12400],visited[2501],dist[2501],tot;
int n,m,s,e;
queue<int> q;
void add_edge(int u,int v,int w)
{
	++tot;
	nxt[tot]=head[u];
	to[tot]=v;
	weight[tot]=w;
	head[u]=tot;
}
void spfa(int index)
{
	int i;
	for(i=1;i<=n;i++)
		dist[i]=index==i?0:INT_MAX;
	visited[index]=1;
	q.push(index);
	while(!q.empty())
	{
		int tmp=q.front();
		q.pop();
		visited[tmp]=0;
		for(i=head[tmp];i;i=nxt[i])
		{
			int v=to[i];
			if(dist[v]>dist[tmp]+weight[i])
			{
				dist[v]=dist[tmp]+weight[i];
				if(!visited[v])
				{
					visited[v]=1;
					q.push(v);
					
				}
			}
		}
	}
}
int main()
{
	int i,j;
	scanf("%d %d %d %d",&n,&m,&s,&e);
	for(i=1;i<=m;i++)
	{
		int u,v,w;
		scanf("%d %d %d",&u,&v,&w);
		add_edge(u,v,w);
		add_edge(v,u,w);
	}
	spfa(s);
	printf("%d",dist[e]);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值