WA求助
查看原帖
WA求助
631550
liuziqin楼主2024/10/15 17:32
#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求出最短路径图,再求出该图的割边。

2024/10/15 17:32
加载中...