五道水题,但要手快才好。。。我手慢了,E题目都没看完TAT....

想了一发,很水,就是一遍Dijk即可,使用优先队列,同时记录由哪条边转移而来

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#define LL long long
using namespace std;

const int MAXN=300050;

struct Edge{
    int u,v,w,i,next;
}edge[MAXN*2];
int weight[MAXN],head[MAXN],tot;
int n,m; int chose[MAXN];
LL dis[MAXN]; bool vis[MAXN];

struct Node{
    int u; LL d;
    Node(){}
    Node(int uu,LL dd){u=uu,d=dd;}
    bool operator<(const Node &a)const{
        return d>a.d;
    }
};

vector <int>ans;
priority_queue<Node>pq;
LL cur;

void addedge(int u,int v,int w,int i){
    edge[tot].u=u; edge[tot].v=v;
    edge[tot].w=w; edge[tot].i=i;
    edge[tot].next=head[u];
    head[u]=tot++;
}

void Dijk(int r){
    cur=0;
    for(int i=1;i<=n;i++) dis[i]=1ll<<62;
    dis[r]=0;
    memset(chose,0,sizeof(chose));
    memset(vis,false,sizeof(vis));
    ans.clear();
    pq.push(Node(r,0));
    while(!pq.empty()){
        Node tmp=pq.top(); pq.pop();
        if(vis[tmp.u]) continue;
        if(tmp.u!=r){
            cur+=weight[chose[tmp.u]];
            ans.push_back(chose[tmp.u]);
        }
        LL d=tmp.d;
        vis[tmp.u]=true;
        for(int e=head[tmp.u];e!=-1;e=edge[e].next){
            int v=edge[e].v;
            if(!vis[v]){
                if(d+edge[e].w<dis[v]){
                    dis[v]=d+edge[e].w;
                    chose[v]=edge[e].i;
                    pq.push(Node(v,dis[v]));
                }
                else if(d+edge[e].w==dis[v]){
                    if(edge[e].w<weight[chose[v]]){
                        chose[v]=edge[e].i;
                    }
                }
            }
        }
    }
    sort(ans.begin(),ans.end());
    cout<<cur<<endl;
    int len=ans.size();
    if(len>0){
        printf("%d",ans[0]);
        for(int i=1;i<len;i++)
        printf(" %d",ans[i]);
        printf("\n");
    }
}

int main(){
    int u,v,w;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(head,-1,sizeof(int)*(n+10));
        tot=0;
        weight[0]=1e9+1000000;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w,i);
            addedge(v,u,w,i);
            weight[i]=w;
        }
        scanf("%d",&u);
        Dijk(u);
    }
    return 0;
}