过样例,保龄求助
查看原帖
过样例,保龄求助
848391
fantastic_dream楼主2023/12/21 20:44

Tarjian+SPFA

#include<bits/stdc++.h>
using namespace std;
const int ma=5e5+5;
int n,m,sz[ma],s,num,head[ma],tot,sq[ma],c,col[ma],dfn[ma],low[ma],cnt,dis[ma],ans,sp[ma];
bool vi[ma];
struct ed{
	int v,ne;
}p[ma];
vector<int> pn[ma];
stack<int> st;
void add(int u,int v){
	p[++tot]={v,head[u]};
	head[u]=tot;
}
void tj(int u){
	st.push(u),dfn[u]=low[u]=++cnt,vi[u]=1;
	for(int i=head[u];i;i=p[i].ne){
		int v=p[i].v;
		if(!dfn[v])	tj(v),low[u]=min(low[u],low[v]);
		else if(vi[v])	low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u]){
		c++;
		while(st.top()!=u){
			int t=st.top();
			st.pop(),col[t]=c,vi[t]=0,sp[c]+=sz[t];
		}
		st.pop(),col[u]=c,vi[u]=0,sp[c]+=sz[u];
	}
}
void spfa(){
	queue<int> q;
	s=col[s],q.push(s),memset(vi,0,sizeof(vi)),dis[s]=sp[s];
	while(!q.empty()){
		int u=q.front();
		vi[u]=0,q.pop();
		for(auto v:pn[u])
			if(dis[v]<dis[u]+sp[v]){
				dis[v]=dis[u]+sp[v];
				if(!vi[v])	vi[v]=1,q.push(v);
			}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	for(int i=1;i<=n;i++)	cin>>sz[i];
	cin>>s>>num;
	for(int i=1;i<=num;i++)	cin>>sq[i];
	for(int i=1;i<=n;i++)	if(!dfn[i])	tj(i);
	for(int i=1;i<=n;i++)
		for(int j=head[i];j;j=p[j].ne){
			int v=p[i].v;
			if(col[v]!=col[i])	pn[col[i]].push_back(col[v]);
		}
	spfa();
	for(int i=1;i<=num;i++)	ans=max(ans,dis[col[sq[i]]]);
	cout<<ans;
	return 0;
}
2023/12/21 20:44
加载中...