记录一下最短路的一些经典例题,当做是模板来用吧。
例题:Title:Agri-Net
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include<stdio.h>
#include<string.h>
#define shuzu 101
int maxn=0x7fffffff;
using namespace std;
int mapp[shuzu][shuzu],vis[shuzu],n,dis[shuzu];
int prime()
{
int i,j,k;
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
for(i=1;i<=n;i++)
dis[i]=mapp[1][i];
vis[1]=1;
int sum=0;
int cont=1;
while(cont<n)
{
int minn=maxn;
for(i=1;i<=n;i++)
if(dis[i]<minn&&vis[i]==0)
{
minn=dis[i];
j=i;
}
cont++;
sum+=minn;
vis[j]=1;
for(k=1;k<=n;k++)
if(vis[k]==0&&mapp[j][k]<dis[k])
dis[k]=mapp[j][k];
}
return sum;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&mapp[i][j]);
mapp[j][i]=mapp[i][j];
}
printf("%d\n",prime());
}
return 0;
}
例题Title:Out of Hay
#include<cstdio>
#include<cstring>
#include<iostream>
#define shuzu 2020
#define MAXN 0x3f3f3f3f
using namespace std;
int map[shuzu][shuzu],n,m;
int dis[shuzu],visit[shuzu];
int prim()
{
int i,j,k,min,maxlen=0;
memset(visit,0,sizeof(visit));
memset(dis,0,sizeof(dis));
for(i=1;i<=n;++i)
dis[i]=map[1][i];
visit[1]=1;
for(i=2;i<=n;++i)
{
min=MAXN;
for(j=1;j<=n;++j)
{
if(!visit[j]&&dis[j]<min)
{
min=dis[j];
k=j;
}
}
if(min!=MAXN&&min>maxlen)
maxlen=min;
visit[k]=1;
for(j=1;j<=n;++j)
{
if(!visit[j]&&dis[j]>map[k][j])
dis[j]=map[k][j];
}
}
return maxlen;
}
int main()
{
int i,j,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;++i)
{
for(j=i;j<=n;++j)
{
if(i==j)
map[i][j]=map[j][i]=0;
else
map[i][j]=map[j][i]=MAXN;
}
}
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;
if(map[a][b]>c)
map[a][b]=map[b][a]=c;
}
printf("%d\n",prim());
}
return 0;
}
例题Title:Silver Cow Party
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int N,M,X;
int MAXN= 10000000;
int MINN=-0x7fffffff;
int dis1[1005],dis2[1005];
int mapp[1005][1005];
char vis[1005];
void chushihua()
{
for(int i=0;i<=N;i++)
for(int j=0;j<=N;j++)
if(i==j)
mapp[i][j]=0;
else
mapp[i][j]=MAXN;
}
void dijkstra(int dis[])
{
for(int i = 0; i <= N; i++)
{
vis[i] = 0;
dis[i] = MAXN;
}
dis[X]=0;
while(1)
{
int v = -1;
for(int u = 1; u <= N; u++)
{
if(!vis[u] && (v < 0 || dis[v] > dis[u]))
v = u;
}
if(v == -1)
break;
vis[v]=1;
for(int j = 1; j <= N; j++)
{
dis[j] = min(dis[j], dis[v] + mapp[v][j]);
}
}
}
int main()
{
while(~scanf("%d%d%d",&N,&M,&X))
{
chushihua();
int a,b,c;
for(int i=1;i<=M;i++)
{
scanf("%d%d%d",&a,&b,&c);
mapp[a][b]=c;
}
dijkstra(dis1);
for(int i=1;i<=N;i++)
for(int j=1;j<i;j++)
{
int temp=mapp[i][j];
mapp[i][j]=mapp[j][i];
mapp[j][i]=temp;
}
dijkstra(dis2);
int maxn=-100000;
for(int i=1;i<=N;i++)
if(i!=X)
maxn=max(maxn,dis1[i]+dis2[i]);
printf("%d\n",maxn);
}
return 0;
}
最短路差不多是一个意思,问的就是从A到B之间最短的路径。
首先初始化dis[]数组为非常大的值,它记录的是从A到其他点的最小值。
第一个大循环的意思是说,从A到另外点的距离有一个最小值,记录这个最小值的下标。
第二个循环的意思是说从从A到一点C,通过C间接到B有一个更小的距离。
举个例子就是说,A->B 100米,A->C 50米,C->B 20米,这时候第二次循环更改为dis[B] = 50+20=70;
写的比较水,大概就是这个意思。