此题是最短路径生成树模板,求调qwq Wa On #8,开了long long,但在原来的题解上有修改
#include<bits/stdc++.h>
#define int long long
#define printlf(x) print(x),putchar('\n')
#define printsp(x) print(x),putchar(' ')
using namespace std;
struct node{
int now,dis;
bool operator <(const node &x) const{
return x.dis<dis;
}
};
const int N=3e5+5,M=3e5+5,INF=2147483647;
struct edge{
int dis,to,next;
}Edge[M<<1];
bool vis[N];
int ans[N],head[N],dis[N],pre[N];
int cnt,sum,n,m,tot;
inline void add(int u,int v,int w){
Edge[++tot].to=v;
Edge[tot].next=head[u];
Edge[tot].dis=w;
head[u]=tot;
}
inline int read(){
int x=0;
bool w=0;
char c=getchar();
while(!isdigit(c)) w|=c=='-',c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
return w?-x:x;
}
inline void print(int x){
if(x<0) x=-x,putchar('-');
if(x>9) print(x/10);
putchar('0'+x%10);
}
inline void Dijkstra(int s){
priority_queue<node> q;
for(register int i=1;i<=n;++i) dis[i]=INF;
q.push({s,0}),dis[s]=0;
while(!q.empty()){
int u=q.top().now;q.pop();
if(vis[u]) continue;
vis[u]=1;
for(register int i=head[u];i;i=Edge[i].next){
int v=Edge[i].to,w=Edge[i].dis;
if(w+dis[u]<dis[v]){
dis[v]=dis[u]+w;
if(!vis[v])q.push({v,dis[v]}),pre[v]=i;
}
if(dis[v]==w+dis[u] && Edge[i].dis<Edge[pre[v]].dis) pre[v]=i;
}
}
}
signed main(){
n=read(),m=read();
for(register int i=1;i<=m;++i){
int u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
}
int s=read();
Dijkstra(s);
for(register int i=1;i<=n;++i){
if(i==s) continue;
int id=pre[i],w=Edge[id].dis;
sum+=w,ans[++cnt]=id;
}
// for(register int i=1;i<=n;++i) cout<<pre[i]<<' ';cout<<endl;
printlf(sum);
sort(ans+1,ans+cnt+1);
for(register int i=1;i<=cnt;++i) printsp((ans[i]+1)>>1);
return 0;
}