众所周知这题是最短路树,然而蒟蒻不会,想了一种方法只有18分,求问!
查看原帖
众所周知这题是最短路树,然而蒟蒻不会,想了一种方法只有18分,求问!
184500
hanzhongtlx楼主2020/11/5 21:37

考虑到这题是要求出有多少只奶牛经过改点,又在该图是正权的前提下。

靠近(最短路树)叶子的点 disdis 一定比他的祖先们大,那就按 disdis 排序,从大到小,递推到最短路的前缀,然后后面就一样了,请问是实现的不对,还是想法有 bug ?

先在这里谢谢了,毕竟大家都要复习qwq

#include"iostream"
#include"cstdio"
#include"cmath"
#include"queue"
using namespace std;

#define N 10005
#define M 50005
#define inf 0x7fffffff
#define read(x) scanf("%d",&x)

int n,m,u,v,w,t;
int we[N];
int dis[N],vis[N],lst[N];
struct node
{
	int to,nxt,w;
}e[M<<1];
int head[N],cnt=0;
int ans=0;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
priority_queue<pair<int,int> >qq;

void add(int u,int v,int w){e[++cnt].to=v,e[cnt].nxt=head[u],e[cnt].w=w;head[u]=cnt;}

void dij()
{
	while(!q.empty())
	{
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=e[i].nxt)
		{
			int j=e[i].to;
			if(dis[j]>dis[u]+e[i].w)
			{
				lst[j]=u,dis[j]=dis[u]+e[i].w;
				q.push(make_pair(dis[j],j));
			}
			else if(dis[j]==dis[u]+e[i].w&&lst[j]>u) lst[j]=u;
		}
	}
	return;
}

void work()
{
	while(!qq.empty())
	{
		int u=qq.top().second;
		qq.pop();
		we[lst[u]]+=we[u];
	}
	return;
}

int main()
{
	read(n),read(m),read(t);
	for(int i=1;i<=n;i++) read(we[i]);
	for(int i=1;i<=m;i++)
	{
		read(u),read(v),read(w);
		add(u,v,w),add(v,u,w);
	}
	for(int i=1;i<=n;i++) dis[i]=inf;
	dis[1]=0,q.push(make_pair(0,1));
	dij();
	for(int i=1;i<=n;i++) qq.push(make_pair(dis[i],i));
	work();
	for(int i=1;i<=n;i++)
	{
		if(t<dis[i]) ans=max(ans,(dis[i]-t)*we[i]);
	}
	printf("%d\n",ans);
	return 0;
}
2020/11/5 21:37
加载中...