这道题复习了下spfa算法
用scanf勉强过的,没有做优化,spfa算法每一步应该是取队列中最小距离的点开始搜索的,这样消除了重复、无效的搜索,但是懒得写最小堆了。。。
#include<iostream>
#include<string>
#include<algorithm>
#include<fstream>
#include<vector>
#include<map>
using namespace std;
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
#define sqr(i) ((i)*(i))
#define pii pair<int,int>
#define mp make_pair
#define FOR(i,b,e) for(int i=b;i<=e;i++)
#define FORE(i,b,e) for(int i=b;i>=e;i--)
#define ms(a) memset(a,0,sizeof(a))
const int maxnum =100003;
const int INF = 10000;
int n,m,s,t;
struct node
{
int next;int dis;
node(){}
node(int n,int d):next(n),dis(d){}
};
struct node2{
int v,dis;
}que[maxnum];
vector<int> p[maxnum];
map<pii,int> edge;
int dis[maxnum];
int check[maxnum];
void spfa(){
int st=0,en=0;
que[0].v=s;
que[0].dis=0;
en++;
while(st!=en){
int now = que[st].v;
int next,ndis;
int si=p[now].size();
FOR(i,0,si-1){
next = p[que[st].v][i];
if(next<=now)
ndis = edge[mp(next,now)];
else
ndis = edge[mp(now,next)];
if(dis[next]>dis[now]+ndis){//可以更新
if(check[next]==-1){
que[en].v=next;
que[en].dis=dis[now]+ndis;
dis[next]=min(dis[next],dis[now]+ndis);
check[next]=en;
en=(en+1)%maxnum;
continue;
}
int pos = check[next];
if(que[pos].dis<=dis[now]+ndis)
continue;
que[pos].dis=dis[now]+ndis;
dis[next]=min(dis[next],que[pos].dis);
}
}
check[now]=-1;
st=(st+1)%maxnum;
}
}
int main()
{
#ifdef _DEBUG_
fstream fin("G:/1.txt");
#else
#define fin cin
#endif
fin>>n>>m>>s>>t;
int a,b,c;
FOR(i,1,m){
//fin>>a>>b>>c;
scanf("%d%d%d",&a,&b,&c);
if(a>b) swap(a,b);
if(edge[mp(a,b)]==0){
edge[mp(a,b)]=c;
p[a].push_back(b);
p[b].push_back(a);
}
else if(c<edge[mp(a,b)])
edge[mp(a,b)]=c;
}
FOR(i,1,n){
dis[i]=INF;
check[i]=-1;
}
dis[s]=0;
spfa();
cout<<dis[t]<<endl;
return 0;
}