bfs 时间卡的比较紧
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#define N 100100
using namespace std;
int head[N],cnt,path[N],dis[N],mm[N];
bool vis[N];
int n;
struct Edge{
int u,v,w,next;
}edge[400100];
struct Point{
int v,sta;
};
void init(){
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
cnt=0;
}
void addedge(int u,int v,int w){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].u=v;
edge[cnt].v=u;
edge[cnt].w=w;
edge[cnt].next=head[v];
head[v]=cnt++;
}
void spfa(){
int i;
for(i=1;i<n;i++)
dis[i]=N*10;
dis[n]=0;
queue<int>q;
q.push(n);
vis[n]=1;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
}
void bfs(){
int i;
queue<int>q;
int q1[N];
q.push(1);
memset(vis,0,sizeof(vis));
bool flag=1;
while(!q.empty()){ //一层一层的搞
int tmp=1100000000,num=0;
if(q.front()==n)break;
while(!q.empty()){
int u=q.front();
q.pop();
for(i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(dis[u]==dis[v]+1){
if(tmp>edge[i].w){
tmp=edge[i].w;
num=0;
q1[num++]=v;
}
else if(tmp==edge[i].w)
q1[num++]=v;
}
}
}
if(flag)printf("%d",tmp),flag=0;
else printf(" %d",tmp);
for(i=0;i<num;i++){
if(vis[q1[i]])continue;
vis[q1[i]]=1; //同一个顶点只能进队一次
q.push(q1[i]);
}
}
}
int main(){
int i,m,u,v,w;
int t,T;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%d %d",&n,&m);
init();
for(i=1;i<=m;i++){
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
}
spfa();
printf("%d\n",dis[1]);
bfs();
printf("\n");
}
return 0;
}
或者也可以这么写
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#define N 100100
using namespace std;
int head[N],cnt,path[N],dis[N],mm[N];
bool vis[N];
int n;
struct Edge{
int u,v,w,next;
}edge[400100];
struct Point{
int v,sta;
};
void init(){
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
cnt=0;
}
void addedge(int u,int v,int w){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].u=v;
edge[cnt].v=u;
edge[cnt].w=w;
edge[cnt].next=head[v];
head[v]=cnt++;
}
void spfa(){
int i;
for(i=1;i<n;i++)
dis[i]=N*10;
dis[n]=0;
queue<int>q;
q.push(n);
vis[n]=1;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
}
void bfs(){
int i;
queue<struct Point>q;
struct Point tem;
tem.v=1,tem.sta=0;
q.push(tem);
for(i=0;i<=n;i++)
path[i]=mm[i]=1100000000;
path[dis[1]]=mm[1]=0;
while(!q.empty()){
struct Point tmp=q.front();
int u=tmp.v,sta=tmp.sta;
q.pop();
if(path[dis[u]]<sta)continue;
for(i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(dis[u]==dis[v]+1){
if(path[dis[v]]>=edge[i].w){
path[dis[v]]=edge[i].w;
if(path[dis[v]]<mm[v]){ //控制同一个点进队列次数
mm[v]=path[dis[v]];
tem.v=v,tem.sta=path[dis[v]];
q.push(tem);
}
}
}
}
}
}
int main(){
int i,m,u,v,w;
int t,T;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%d %d",&n,&m);
init();
for(i=1;i<=m;i++){
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
}
spfa();
printf("%d\n",dis[1]);
bfs();
printf("%d",path[dis[1]-1]);
for(i=dis[1]-2;i>=0;i--)
printf(" %d",path[i]);
printf("\n");
}
return 0;
}