来源:JZOJ #313,Luogu P1339
题目描述
德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他们的德克萨斯长角牛吃起来不错,可是他们并不是很擅长生產富含奶油的乳製品。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)最小的总费用。
解题思路
- 这是一道 的模板题,用邻接矩阵存储图,开一个 数组, 表示从起点到点 的最小费用。很显然,最后输出的是
代码君
#include <bits/stdc++.h>
using namespace std;
int a[2505][2505],dis[2505],f[2505];
int n,m,st,end;
void dijkstra() //迪杰斯特拉板子
{
for (int i=1;i<=n;i++) dis[i]=a[st][i]; //初值,起点到i的距离肯定是a[st][i]
memset(f,0,sizeof(f)); //清空标记数组
f[st]=1;dis[st]=0; //起点距离起点为0
for (int i=1;i<=n-1;i++) //起点不用再迭代,一共执行n-1次
{
int Min=0xfffffff,Min_i=0;
for (int j=1;j<=n;j++)
if (f[j]==0 && dis[j]<Min) //在未求点中找距离起点最近的一个点k,记录
{
Min=dis[j];
Min_i=j; //记录点
}
if (Min_i==0) return; //如果找不到了,说明没有未求点了
f[Min_i]=1; //把点k作标记
for (int j=1;j<=n;j++) //三角形迭代,看未求点中是否有点经过k距离变短
if (f[j]==0 && dis[Min_i]+a[Min_i][j]<dis[j])
{
dis[j]=dis[Min_i]+a[Min_i][j];
}
}
}
int main()
{
freopen("heatwv.in","r",stdin);
freopen("heatwv.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&st,&end);
memset(a,10,sizeof(a));
for (int i=1;i<=m;i++)
{
int x,y,v;
scanf("%d %d %d",&x,&y,&v);
a[x][y]=min(a[x][y],v); //邻接矩阵存储无向图
a[y][x]=min(a[y][x],v);
}
for (int i=1;i<=n;i++) a[i][i]=0; //初值
dijkstra();
printf("%d",dis[end]); //输出
return 0;
}