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;
}