悬2关求助
  • 板块灌水区
  • 楼主ChenZQ
  • 当前回复18
  • 已保存回复18
  • 发布时间2024/12/4 20:40
  • 上次更新2024/12/4 22:43:27
查看原帖
悬2关求助
745358
ChenZQ楼主2024/12/4 20:40

https://www.luogu.com.cn/problem/P3627

样例能过,提交全wa,我的思路是先缩点,求出缩点后每个点如果原来有休息站那么这个点就能停,每个点是那个缩的点内所有钱的总和。缩点后从s开始跑最长路。

#include <bits/stdc++.h>
using namespace std;

const int N = 500010;
int h[N],e[N<<1],ne[N<<1],idx,dfn[N],low[N];
int f[N];
int a[N],s,p,col[N],vw[N],x[N],y[N];
bool xx[N],rest[N],vis[N];
int tot=1;
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int n,m;
int co=0;
stack<int> stk;
void dfs(int u,int f)
{
	dfn[u]=tot++,low[u]=tot-1;
	stk.push(u);
	vis[u]=1;
	for(int i=h[u];i!=-1;i=ne[i])
	{
		if(!dfn[e[i]])
		{
			dfs(e[i],u);
			low[u]=min(low[u],low[e[i]]);
		}
		if(vis[e[i]]) low[u]=min(low[u],dfn[e[i]]);
	}
	if(low[u]==dfn[u])
	{
		int x=-1;
		co++;
		while(x!=u)
		{
			x=stk.top();
			stk.pop();
			col[x]=co;
			vw[co]+=a[x];
			vis[x]=0;
			if(xx[x]) rest[co]=1;
		}
	}
}
vector<int> v[N];
int dist[N];
struct node
{
	int u,x;
	bool operator < (const node&cmp) const
	{
		return x<cmp.x;
	}
};
int flag[N];
priority_queue<node> q;
int main()
{
	scanf("%d%d",&n,&m);
	memset(h,-1,sizeof h);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x[i],&y[i]);
		add(x[i],y[i]);
	}
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d%d",&s,&p);
	for(int i=1;i<=p;i++)
	{
		int a;
		scanf("%d",&a);
		xx[a]=1;
	}
	dfs(1,1);

	for(int i=1;i<=m;i++)
	{
		if(col[x[i]]!=col[y[i]]) 
		{
			int a=col[x[i]],b=col[y[i]];
			v[a].push_back(b);
		}
	}
	q.push({col[s],vw[col[s]]});flag[col[s]]=1;
	dist[col[s]]=vw[col[s]];
	while(!q.empty())
	{
		node f=q.top();
		q.pop();
		int t=v[f.u].size();
		for(int i=0;i<t;i++)
		{
			if(dist[f.u]+vw[v[f.u][i]]>dist[v[f.u][i]])
			{
				dist[v[f.u][i]]=dist[f.u]+vw[v[f.u][i]];
				if(!flag[v[f.u][i]])
				{
					flag[v[f.u][i]]=1;
					q.push({v[f.u][i],dist[v[f.u][i]]});
				}
			}
		}
	}
	int mx=0;
	for(int i=1;i<=co;i++)
	{
		if(rest[i]) mx=max(mx,dist[i]);
	}
	printf("%d",mx);
}
2024/12/4 20:40
加载中...