#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=200005;
map<int,map<int,int> >mp;
int u[N],v[N],w[N];
bool is[N],must[N];
int n,m;
struct graph{
struct edge{
int to,nxt,w;
}e[N<<1];
int head[N],cnt;
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].nxt=head[u];
e[cnt].w=w;
head[u]=cnt;
}
int dis[N];
bool used[N];
void dij(){
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
memset(used,0,sizeof(used));
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push({0,1});
while(!q.empty()){
int u=q.top().second;
q.pop();
if(used[u])continue;
used[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push({dis[v],v});
}
}
}
}
int low[N],dfn[N],idx=0;
void tarjan(int u,int fa){
low[u]=dfn[u]=++idx;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
is[mp[v][u]]=1;
}
}
else if(dfn[v]<dfn[u]&&v!=fa)low[u]=min(low[u],dfn[v]);
}
}
bool vis[N],can[N];
bool getans(int u){
if(vis[u])return can[u];
if(u==n)return 1;
vis[u]=1;
bool sum=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,id=mp[u][v];
bool t=getans(v);
sum|=t;
if(t&&is[id])must[id]=1;
}
can[u]=sum;
return sum;
}
}g1,g2;
signed main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u[i]>>v[i]>>w[i];
g1.add(u[i],v[i],w[i]);
g1.add(v[i],u[i],w[i]);
mp[u[i]][v[i]]=mp[v[i]][u[i]]=i;
}
g1.dij();
for(int i=1;i<=m;i++){
if(g1.dis[u[i]]+w[i]==g1.dis[v[i]]){
g2.add(u[i],v[i],1);
g2.add(v[i],u[i],1);
}
if(g1.dis[v[i]]+w[i]==g1.dis[u[i]]){
g2.add(v[i],u[i],1);
g2.add(v[i],u[i],1);
}
}
g2.tarjan(1,0);
g2.getans(1);;
for(int i=1;i<=m;i++){
if(must[i])cout<<"Yes\n";
else cout<<"No\n";
}
return 0;
}
我的思路是跑一遍dijkstra求出最短路径图,再求出该图的割边。