题意:告诉n个点和m条边,求s到t的最短路径。。
思路:N和M都比较大了,n有20000,m有50000,用邻接表加SPFA。
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define INF 99999999
using namespace std;
int n,m,s,t;
int dis[22222];
int vis[22222];
int f[22222];
int nt[100009];
int u[100009],v[100009],w[100009];
void read_()
{
memset(f,-1,sizeof f);
for(int i=0;i<m*2;i+=2)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
nt[i]=f[u[i]]; f[u[i]]=i; //以u[i]开头的是第i个
u[i+1]=v[i]; v[i+1]=u[i]; w[i+1]=w[i]; //无向图
nt[i+1]=f[u[i+1]]; f[u[i+1]]=i+1;
}
}
void SPFA()
{
queue<int>q;
for(int i=0;i<=n;i++)
{
vis[i]=0;dis[i]=INF;
}
dis[s]=0;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
vis[x]=0;
for(int i=f[x];i!=-1;i=nt[i])
if(dis[x]+w[i]<dis[v[i]])
{
dis[v[i]]=dis[x]+w[i];
if(vis[v[i]]==0)
{
vis[v[i]]=1;
q.push(v[i]);
}
}
}
if(dis[t]==INF)
puts("unreachable");
else
printf("%d\n",dis[t]);
}
int main()
{
int T;
int a,b,c;
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
scanf("%d%d%d%d",&n,&m,&s,&t);
read_();
printf("Case #%d: ",ca);
SPFA();
}
return 0;
}