先枚举删一条边,然后找出新图中所有的桥,可以发现如果一条边是桥且在 ss 到 的路径上,将其删去一定会使 ss 与 不连通。求个最小值就好了。
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
const int M=30010;
int k,n,m,S,T,x,y;
int w[M];
int t[M<<1],nx[M<<1],h[N],num=1;
int Ans=INT_MAX,c1,c2;
int dfn[N],low[N],tc;
bool v[N],b[M];
vector<int>g,G;
inline void Add(int x,int y){
t[++num]=y;nx[num]=h[x];h[x]=num;
}
bool Dfs(int x,int y,int d){
v[x]=1;
if(x==y)return 1;
for(int i=h[x];i;i=nx[i])
if((i>>1)!=d&&!v[t[i]]&&Dfs(t[i],y,d)){
g.push_back(i>>1);
return 1;
}
return 0;
}
bool Dfs1(int x,int y){
v[x]=1;
if(x==y)return 1;
for(int i=h[x];i;i=nx[i])
if(!v[t[i]]&&Dfs1(t[i],y)){
G.push_back(i>>1);
return 1;
}
return 0;
}
void Tarjan(int x,int y,int d){
dfn[x]=low[x]=++tc;
bool fl=0;
for(int i=h[x];i;i=nx[i])
if((i>>1)!=d){
if(t[i]==y&&!fl){
fl=1;
continue;
}
if(!dfn[t[i]]){
Tarjan(t[i],x,d);
low[x]=min(low[x],low[t[i]]);
if(low[t[i]]>dfn[x])b[i>>1]=1;
}else low[x]=min(low[x],dfn[t[i]]);
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&w[i]),Add(x,y),Add(y,x);
if(!Dfs1(S,T)){
printf("0\n0\n");
return 0;
}
for(int i=0;i<G.size();i++){
x=G[i];
g.clear();
memset(v,0,sizeof(v));
if(!Dfs(S,T,x)){
if(w[x]<Ans)Ans=w[x],c1=x,c2=0;
}else{
memset(b,0,sizeof(b));
memset(dfn,0,sizeof(dfn));
tc=0;
for(int j=1;j<=n;j++)
if(!dfn[j])Tarjan(j,0,x);
for(int j=0;j<g.size();j++)
if(b[g[j]]&&w[x]+w[g[j]]<Ans)Ans=w[x]+w[g[j]],c1=x,c2=g[j];
}
}
if(Ans==INT_MAX)puts("-1");else{
printf("%d\n",Ans);
if(!c2)printf("1\n%d\n",c1);else printf("2\n%d %d\n",c1,c2);
}
return 0;
}