最短路吧,老师把SPFA卡了让我们知道SPFA是一个辣鸡的算法 (逃
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define MAXM 400010
#define ll long long
const ll inf=1e16;
struct edge{
int to,nxt,val,pos;
}e[MAXM<<1],E[MAXM<<1];
struct node{
int num; ll dis;
bool operator<(node b) const
{
return dis>b.dis;
}
};
int dfn[MAXN],low[MAXN],col[MAXN];
ll dis[MAXN];
int ans;
int head[MAXN],head1[MAXN];
bool vis[MAXN];
int num,cnt,n,m;
void add_edge(int u,int v,int w,int g)
{
e[++num].to=v;
e[num].nxt=head[u];
e[num].val=w;
e[num].pos=g;
head[u]=num;
e[++num].to=u;
e[num].nxt=head[v];
e[num].val=w;
e[num].pos=g;
head[v]=num;
}
void Add_edge(int u,int v,int w)
{
E[++num].to=v;
E[num].nxt=head1[u];
E[num].pos=w;
head1[u]=num;
E[++num].to=u;
E[num].nxt=head1[v];
E[num].pos=w;
head1[v]=num;
}
priority_queue<node>q;
void dij()
{
for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=0;
dis[1]=0,q.push((node){1,0});
while (!q.empty())
{
node x=q.top(); q.pop();
if (vis[x.num]) continue;
vis[x.num]=1;
for (int i=head[x.num];i;i=e[i].nxt)
{
int v=e[i].to;
if(dis[v]>dis[x.num]+e[i].val)
{
dis[v]=dis[x.num]+e[i].val;
q.push((node){v,dis[v]});
}
}
}
}
void Dfs(int x)
{
vis[x]=1;
for (int i=head[x];i; i=e[i].nxt)
{
int v=e[i].to;
if (dis[x]!=dis[v]+e[i].val) continue;
Add_edge(v,x,e[i].pos);
if(vis[v]) continue;
Dfs(v);
}
}
void Tarjan(int x,int fa)
{
low[x]=dfn[x]=++cnt;
for (int i=head1[x];i;i=E[i].nxt)
{
int v=E[i].to;
if (!dfn[v])
{
if(E[i].pos==fa) continue;
Tarjan(v,E[i].pos);
low[x]=min(low[x],low[v]);
if(low[v]>dfn[x]) col[E[i].pos]=1,ans++;
}
else if(dfn[v]<dfn[x] && E[i].pos!=fa) low[x]=min(low[x],dfn[v]);
}
}
void Rebuild()
{
num=0;
for(int i=1;i<=n;i++) vis[i]=0;
Dfs(n);
}
void Get_ans()
{
num=0;
Tarjan(1,0);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m; ++i)
{
int u,v,w;scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w,i);
}
dij();
Rebuild();
Get_ans();
printf("%d\n",ans);
for(int i=1;i<=m;i++) if(col[i]) printf("%d ",i);
return 0;
}
来源:zr