• [省选联考 2021 A/B 卷] 图函数


    考虑到一件事情首先\(u -> u\)是可行的。
    所以其实对于\(f(u,G')\) 只要考虑\([1,u]\)的点。
    那么考虑其条件等价于\(u -> i\)\(i -> u\) 都不经过\([1,u)\)的点。
    不然我们显然可以构造出一种情况,使得在路径上某个点被删掉。

    那么考虑我们对全局进行一个答案的求。
    考虑我们设\(g(x,y)\) 满足给定条件。
    那么接着考虑我们的这个边的条件。
    我们只要求出这个\(i -> j\)限定只能经过\([k + 1,n]\)这些点的最小值的最大值即可。

    直接folyd,O(n^3).
    考虑加入一波优化。
    我们在限制\(i > lim\)时只更新小于\(lim\)的量即可少一半常数。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #define ll long long 
    #define N 1005
    #define M 200005
    
    int n,m;
    int f[N][N];
    int ans[M]; 
    int g[M];
    
    int main(){
    //	freopen("graph.in","r",stdin);
    //	freopen("graph.out","w",stdout);	
    	scanf("%d%d",&n,&m);
    	for(int i = 1;i <= m;++i){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		f[u][v] = i;
    	}
    	for(int lim = n;lim >= 1;--lim){//点的限制
    		for(int i = n;i >= lim + 1;--i)
    //		for(int i = 1;i < lim;++i)
    		g[std::min(f[lim][i],f[i][lim])] ++ ;
    		for(int i = 1;i <= n;++i){
    			if(!f[i][lim])continue;
    			if(i > lim)
    			for(int j = 1;j < lim;++j)
    			f[i][j] = std::max(f[i][j],std::min(f[i][lim],f[lim][j]));			
    			else
    			for(int j = 1;j <= n;++j)
    			f[i][j] = std::max(f[i][j],std::min(f[i][lim],f[lim][j]));
    		}
    	}
    	ans[m + 1] = n;
    	for(int i = m;i >= 1;i--)
    	ans[i] = ans[i + 1] + g[i];
    	for(int i = 1;i <= m + 1;++i)
    	std::cout<<ans[i]<<" ";
    }
    
    
    
  • 相关阅读:
    有关TSQL中的ROUND()的用法
    孤立用户
    微小的边缘原理
    分段统计查询的方法
    虎尾兰
    有规律字段的拆分
    对索引视图的限制
    金额转换为英文大写
    经典名言
    最大信息熵原理
  • 原文地址:https://www.cnblogs.com/dixiao/p/15599023.html
Copyright © 2020-2023  润新知