zoukankan      html  css  js  c++  java
  • [CF1483D] Useful Edges

    前言

    如果你毫无思路,考虑暴力!然后优化它!

    题目

    CF

    洛谷

    讲解

    如果你想容斥,那么你已经没救了。

    ( t Floyd) 应该不用讲吧。

    我们先想暴力,枚举一条边,然后在三元组里面检验,时间复杂度是 (O(mq)=O(n^4))

    我们发现枚举边似乎不是很能优化,于是我们考虑是否能够不枚举三元组。

    我们把一条边是好边的条件写下来:存在一个三元组 (l_{i,j}ge dis_{i,u}+w_{u,v}+dis_{v,j})

    移项: (l_{i,j}-dis_{i,u}ge w_{u,v}+dis_{v,j})

    我们发现 (RHS) 已经和 (i) 无关,可以 (O(nm)) 做,这时我们只需要知道 (LHS) 即可。

    (LHS) 最大值为 (MAX_{j,u}),显然可以用 (O(qn)) 的时间复杂度预处理,注意一个三元组中的 (l) 既可以代表 (l_{i,j}) 也可以代表 (l_{j,i})

    此时时间复杂度已经降为了 (O(n^3)) 级别。

    代码

    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); m = Read();
    	for(int i = 1;i <= n;++ i) 
    		for(int j = 1;j <= n;++ j)
    			if(i ^ j) dis[i][j] = INF;
    	for(int i = 1;i <= m;++ i)
    	{
    		u[i] = Read(),v[i] = Read(),w[i] = Read();
    		dis[u[i]][v[i]] = dis[v[i]][u[i]] = w[i];
    	}
    	for(int k = 1;k <= n;++ k)
    		for(int i = 1;i <= n;++ i)
    			for(int j = 1;j <= n;++ j)
    				dis[i][j] = Min(dis[i][j],dis[i][k]+dis[k][j]);
    	for(int Q = Read(); Q ;-- Q)
    	{
    		int i = Read(),j = Read(),l = Read();
    		for(int u = 1;u <= n;++ u) MAX[j][u] = Max(MAX[j][u],l-dis[i][u]),MAX[i][u] = Max(MAX[i][u],l-dis[j][u]);
    	}
    	for(int i = 1;i <= m;++ i)
    		for(int j = 1;j <= n;++ j)
    			if(MAX[j][u[i]] >= w[i]+dis[v[i]][j])
    			{
    				ans++;
    				break;
    			}
    	Put(ans);
    	return 0;
    }
    
  • 相关阅读:
    ubuntu下mysql的安装
    useradd和adduser的区别
    C和指针之学习笔记(6)
    C和指针之学习笔记(5)
    C和指针之学习笔记(4)
    Centos 7搭建Gitlab服务器超详细
    .NET Core sdk和runtime区别
    .NET平台历程介绍
    GitLabCICD
    Jenkins+gitlab+msbuild
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14791932.html
Copyright © 2011-2022 走看看