http://acm.nyist.net/JudgeOnline/problem.php?pid=115
简单的最短路问题;
#include<stdio.h>
const int maxnum=1002;
const int maxint=100005;
void Dijkstra(int n,int v,int *dist,int c[maxnum][maxnum])
{
int s[maxnum]; // 判断是否已存入该点到S集合中
for(int i=1;i<=n;i++)
{
dist[i]=c[v][i]; //暴乱城市到个点的距离。
s[i]=0; // 初始都未用过该点
}
dist[v]=0;
s[v]=1;
// 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
// 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
for(int i=2;i<=n;++i)
{
int tmp=maxint;
int u=v;
// 找出当前未使用的点j的dist[j]最小值
for(int j=1;j<=n;++j)
if((!s[j])&&dist[j]<tmp)
{
u=j; // u保存当前邻接点中距离最小的点的号码
tmp=dist[j];
}
s[u]=1; // 表示u点已存入S集合中
for(int j=1;j<=n;++j) // 更新dist
if((!s[j])&&c[u][j]<maxint)
{
int newdist=dist[u]+c[u][j];
if(newdist<dist[j])
dist[j]=newdist;
}
}
}
int main()
{
// 各数组都从下标1开始
int dist[maxnum]; // 表示当前点到源点的最短路径长度
int army[102];//部队数;
int c[maxnum][maxnum]; // 记录图的两点间路径长度
int n,line,ncase,N,Q;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d%d%d%d",&N,&n,&line,&Q);
for(int i=1;i<=N;i++)
scanf("%d",&army[i]); //部队所在的城市。
int p,q,len; // 输入p, q两点及其路径长度
for(int i=1;i<=n;++i) // 初始化c[][]为maxint,表示边不存在。
for(int j=1;j<=n;++j)
c[i][j]=maxint;
for(int i=1;i<=line;++i)
{
scanf("%d%d%d",&p,&q,&len);
if(c[p][q]>len) //两个城市不止一条路。
{
c[p][q]=len;
c[q][p]=len;
}
}
for(int i=1;i<=n;++i)
dist[i]=maxint;
Dijkstra(n,Q,dist,c);
int min=99999;
for(int j=1;j<=N;j++)
if(min>dist[army[j]])
min=dist[army[j]];
printf("%d\n",min);
}
return 0;
}
用队列优化但是未用邻接表:
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
#define inf 0x7fffffff //inf表示无穷大
int N,edge[1002][1002],distD[1002],i,j;
int army[1002],M,P,Q;
typedef pair<int,int> ele;//STL中。
void init()
{
for(i=1;i<=N;i++) //结点坐标都是从1开始的
for(j=1;j<=N;j++)
{
if(i==j)
edge[i][j]=0;
else
edge[i][j]=inf;
}
}
void Dijstra(int v)
{
for(i=1;i<=N;i++)
{
distD[i]=edge[v][i]==0?0:inf;
}
priority_queue<ele,vector<ele>,greater<ele> > D;
D.push(make_pair(distD[v],v));
while(!D.empty())
{
ele u=D.top(); D.pop();
int x=u.second;
if(distD[x]!=u.first)
continue;
for(j=1;j<=N;j++)
if(edge[x][j]<inf&&distD[x]+edge[x][j]<distD[j])
{
distD[j]=distD[x]+edge[x][j];
D.push(make_pair(distD[j],j));
}
}
int min=99999;
for(int i=1;i<=M;i++)
if(min>distD[army[i]])
min=distD[army[i]];
printf("%d\n",min);
}
int main()
{
int a,b,c,ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d%d%d%d",&M,&N,&P,&Q);// 军队数,城市数,公路条数,暴乱城市。
init();
for(int i=1;i<=M;i++)
scanf("%d",&army[i]);
for(int i=1;i<=P;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge[a][b]=c;
edge[b][a]=c;
}
Dijstra(Q);
}
return 0;
}