2021桂林-Tax-(spfa+dfs路径)

K

题意:
就是给你n点m个边,每条边被其中一个公司管理,现在你从一号点开始出发,对于到达任意一点有很多条路径,你会选择最短的路径,同时对于多个最短的路径选花费最少的那个。对于花费的计算就是,你走的这条路径,每条边走过的次数✖这条边属于那个公司的权值。

思考:
对于从1到任一点的最短路很明显,就是一遍spfa就行了。但是对于到某一点如何确定权值最小的怎么找呢。其实看到数据范围n为50,就可以发现,可以直接爆搜,但是要注意,只有dist[spot]==dist[now]+1的时候,才可以过去,为什么呢,既然是最短路,肯定从这个点走一次就到达了另一个点。这样就不会超时了,虽然n是50。但是还是超时呢,因为开longlong了,所以尽量不开long long的还是不开把。

代码:

int T,n,m,k;
int va[N];
int dist[N],vis[N];
int cnt[N],anw[N];

vector<PII > e[N];

void spfa()
{
	for(int i=1;i<=n;i++) dist[i] = inf;
	queue<int > q;
	q.push(1);
	dist[1] = 0;vis[1] = 1;
	while(q.size())
	{
		auto now = q.front();
		q.pop();
		vis[now] = 0;
		for(auto t:e[now])
		{
			int spot = t.fi;
			if(dist[spot]>dist[now]+1)
			{
				dist[spot] = dist[now]+1;
				if(!vis[spot])
				{
					vis[spot] = 1;
					q.push(spot);
				}
			}
		}
	}
}

void dfs(int now,int sum)
{
	anw[now] = min(anw[now],sum);
	for(auto t:e[now])
	{
		int spot = t.fi,id = t.se;
		if(dist[spot]==dist[now]+1)
		{
			cnt[id]++;
			dfs(spot,sum+cnt[id]*va[id]);
			cnt[id]--;
		}
	}
}

signed main()
{
	IOS;
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>va[i];
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		e[a].pb({b,c});
		e[b].pb({a,c});
	}
	spfa();
	for(int i=1;i<=n;i++) anw[i] = inf;
	dfs(1,0);
	for(int i=2;i<=n;i++) cout<<anw[i]<<"\n";
	return 0;
}

总结:
多多思考和总结。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值