环境治理、染色时间、小蓝组网

环境治理

环境治理

问题描述

LQ 国拥有 nn 个城市, 从 0 到 n−1n−1 编号, 这 nn 个城市两两之间都有且仅有 一条双向道路连接, 这意味着任意两个城市之间都是可达的。每条道路都有一 个属性 DD, 表示这条道路的灰尘度。当从一个城市 AA 前往另一个城市 BB 时, 可 能存在多条路线, 每条路线的灰尘度定义为这条路线所经过的所有道路的灰尘 度之和, LQ 国的人都很讨厌灰尘, 所以他们总会优先选择灰尘度最小的路线。

LQ 国很看重居民的出行环境, 他们用一个指标 PP 来衡量 LQ 国的出行环 境, PP 定义为:

P=∑i=0n−1∑j=0n−1d(i,j)P=i=0∑n−1​j=0∑n−1​d(i,j)

其中 d(i,j)d(i,j) 表示城市 ii 到城市 jj 之间灰尘度最小的路线对应的灰尘度的值。 为了改善出行环境, 每个城市都要有所作为, 当某个城市进行道路改善时, 会将与这个城市直接相连的所有道路的灰尘度都减少 1 , 但每条道路都有一个 灰尘度的下限值 LL, 当灰尘度达到道路的下限值时, 无论再怎么改善, 道路的 灰尘度也不会再减小了。

具体的计划是这样的:

第 1 天, 0 号城市对与其直接相连的道路环境进行改善;

第 2 天, 1 号城市对与其直接相连的道路环境进行改善;

⋯⋯

第 nn 天, n−1n−1 号城市对与其直接相连的道路环境进行改善;

第 n+1n+1 天, 0 号城市对与其直接相连的道路环境进行改善;

第 n+2n+2 天, 1 号城市对与其直接相连的道路环境进行改善;

LQ 国想要使得 PP 指标满足 P≤QP≤Q 。请问最少要经过多少天之后, PP 指标 可以满足 P≤QP≤Q 。如果在初始时就已经满足条件, 则输出 0 ; 如果永远不可能 满足, 则输出 −1−1 。

输入格式

输入的第一行包含两个整数 n,Qn,Q, 用一个空格分隔, 分别表示城市个数和 期望达到的 PP 指标。

接下来 nn 行, 每行包含 nn 个整数, 相邻两个整数之间用一个空格分隔, 其 中第 ii 行第 jj 列的值 Dij(Dij=Dji,Dii=0)Dij​(Dij​=Dji​,Dii​=0) 表示城市 ii 与城市 jj 之间直接相连 的那条道路的灰尘度。

接下来 nn 行, 每行包含 nn 个整数, 相邻两个整数之间用一个空格分隔, 其 中第 ii 行第 jj 列的值 Lij(Lij=Lji,Lii=0)Lij​(Lij​=Lji​,Lii​=0) 表示城市 ii 与城市 jj 之间直接相连的 那条道路的灰尘度的下限值。

输出格式

输出一行包含一个整数表示答条。

样例输入

复制代码
3 10
0 2 4
2 0 1
4 1 0
0 2 2
2 0 0
2 0 0

样例输出

复制代码
2

评测用例规模与约定

对于 30%30% 的评测用例, 1≤n≤10,0≤Lij≤Dij≤101≤n≤10,0≤Lij​≤Dij​≤10 ;

对于 60%60% 的评测用例, 1≤n≤50,0≤Lij≤Dij≤1000001≤n≤50,0≤Lij​≤Dij​≤100000;

对于所有评测用例, 1≤n≤100,0≤Lij≤Dij≤100000,0≤Q≤231−11≤n≤100,0≤Lij​≤Dij​≤100000,0≤Q≤231−1 。

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;


public class Main {

    static int N=110,M=2*10010,MAX_CNT=2*10000010;     
       
    static int n,q;
    static int id=1;
    
    static int cnt=-1;
   
    static int dd[][]=new int[N][N];
    static int d[][]=new int[N][N];
    static int L[][]=new int[N][N];
    
    
    
    
//    static int h[]=new int[M];
//    static int e[]=new int[M];
//    static int ne[]=new int[M];
//    static int w[]=new int[M];
//    static boolean f[]=new boolean[10010];//是否确定了最短路径
    
    
    
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
    
    public static void main(String[] args) throws IOException { 
    	
        StringTokenizer st=new StringTokenizer(br.readLine());
        n=Integer.parseInt(st.nextToken());  
        q=Integer.parseInt(st.nextToken());
    	
        for (int i = 1; i <= n; i++) {
        	st=new StringTokenizer(br.readLine());
        	for (int j = 1; j <= n; j++) {
				d[i][j]=Integer.parseInt(st.nextToken());
				d[j][i]=d[i][j];
			}
        }
        
        for (int i = 1; i <= n; i++) {
        	st=new StringTokenizer(br.readLine());
			for (int j = 1; j <= n; j++) {
				L[i][j]=Integer.parseInt(st.nextToken());
				L[j][i]=L[i][j];
			}
		}
        
       //对于每一个城市i (这里我们编号从一开始) 给定一个时刻t  我们需要知道他被改善的次数
       //次数等于t/n+(i<=t?1:0)也就是说先看看n个城市同时被改善的次数是多少
       //然后再加上剩下的次数 这个剩下的次数取决于i和t的大小
        
        
        //用二分枚举t
        int l=0,r=MAX_CNT;//保证都能取到下限值嗯
        while(l<r){
        	int mid=(l+r)>>1;
        	if(calc(mid)){
        		r=mid;
        	}else{
        		l=mid+1;
        	}
        }
        
        bw.write(cnt+"");
        
    	
        br.close();
        bw.flush();
        bw.close();
    }
    
    
    static boolean calc(int u){
    	int imporve[]=new int[n+1];//经过t天每个城市的改善次数
    	
    	for (int i = 1; i <= n; i++) {
			imporve[i]=u/n+(i-1<u%n?1:0);//注意没有等号
		}
    	for (int i = 0; i < N; i++) {
			System.arraycopy(d[i], 0, dd[i], 0, N);
		}
    	
    	for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				dd[i][j]=Math.max(L[i][j], dd[i][j]-imporve[i]-imporve[j]);
			}
		}
    	
    	//弗洛伊德算法
    	for (int k = 1; k <= n; k++) {
			for (int i = 1; i <= n; i++) {
				for (int j = 1; j <= n; j++) {
					dd[i][j]=Math.min(dd[i][j],dd[i][k]+dd[k][j]);
				}
			}
		}
    	
    	int res=0;
    	for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				res+=dd[i][j];
			}
		}
    	
    	if(res<=q){
    		cnt=u;
    		return true;
    	}
    	
    	return false;
    }
    
//    static void add(int a,int b,int c){
//    	e[id]=b;    	
//    	ne[id]=h[a];  
//    	w[id]=c;
//    	h[a]=id++;
//    }
       
}

染色时间

问题描述

小蓝有一个 nn 行 mm 列的白色棋盘, 棋盘的每一个方格都可以被染成彩色。

每个方格有一个染色时间 tijtij​, 不同方格的染色时间可能不同。如果一个方 格被触发了染色, 这个方格就会在 tijtij​ 秒之后变成彩色, 然后将自己上下左右四 个方向相邻的方格触发染色。每个方格只能被触发染色一次, 第一次触发之后 的触发为无效触发。

给定每个方格的染色时间, 在时刻 0 触发第一行第一列的方格染色, 请问 多长时间后整个棋盘完成染色。

输入格式

输入的第一行包含两个整数 n,mn,m, 分别表示棋盘的行数和列数。

接下来 nn 行, 每行 mm 个正整数, 相邻的整数之间用一个空格分隔, 表示每 个方格的染色时间。该部分的第 ii 行第 jj 个整数表示 tijtij​, 即第 ii 行第 jj 列的方 格的染色时间。

输出格式

输出一行包含一个整数, 表示整个棋盘完成染色的时间。

样例输入

复制代码
2 3

1 2 3

4 5 6

样例输出

复制代码
12

评测用例规模与约定

对于 3030 的评测用例, 1≤n,m≤101≤n,m≤10 。

对于 6060 的评测用例, 1≤n,m≤501≤n,m≤50 。

对于所有评测用例, 1≤n,m≤500,1≤tij≤10001≤n,m≤500,1≤tij​≤1000 。

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;


public class Main {

    static int N=510;     
       
    static int n,m;
    static int id=1;
    
    static int cnt=-1;
   
    static boolean f[][]=new boolean[N][N];//当前点是否已经被染色
    static int a[][]=new int[N][N];
    static int dist[][]=new int[N][N];
    static int dx[]={0,-1,0,1};
    static int dy[]={1,0,-1,0};
    
    
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
    
    public static void main(String[] args) throws IOException { 
    	
        StringTokenizer st=new StringTokenizer(br.readLine());
        n=Integer.parseInt(st.nextToken());  
        m=Integer.parseInt(st.nextToken());
    	
        for (int i = 1; i <= n; i++) {
        	st=new StringTokenizer(br.readLine());
			for (int j = 1; j <= m; j++) {
				a[i][j]=Integer.parseInt(st.nextToken());
			}
		}
        
        int res=0;
        //不可用BFS
        PriorityQueue<int[]> queue=new PriorityQueue<>((a,b)->a[2]-b[2]);
        queue.add(new int[]{1,1,a[1][1]});
        for (int i = 0; i < N; i++) {
			Arrays.fill(dist[i], Integer.MAX_VALUE);
		}
        dist[1][1]=a[1][1];
        while(!queue.isEmpty()){
        	int no[]=queue.poll();
        	int x=no[0],y=no[1],cur=no[2];
        	
        	if(!f[x][y]){
        		f[x][y]=true;
        		for (int i = 0; i < 4; i++) {
    				int nx=x+dx[i],ny=y+dy[i];
    				if(nx<1 || nx>n || ny<1 || ny>m)continue;
    				if(!f[nx][ny]){
    					if(cur+a[nx][ny]<dist[nx][ny]){
	    					dist[nx][ny]=cur+a[nx][ny];
	    					res=Math.max(res, dist[nx][ny]);
	    					queue.add(new int[]{nx,ny,dist[nx][ny]});
    					}
    					
    				}
    			}
        	}
        	
        }
        
        bw.write(res+"");
    	
        br.close();
        bw.flush();
        bw.close();
    }
    
    
       
}

小蓝组网

问题描述

给定一个含有 nn 个结点和 mm 条边的无向图,图中所有边的权值均为 11 ,且图中不包含重边。请判断该图中各点是否连通,并给出图中两个连通的点之间最短距离的最大值。

输入格式

输入第 11 行包括两个整数 n,mn,m ,分别表示图中结点的个数与边的个数。

第 2∼m+12∼m+1 行,每行包括两个整数 a,ba,b ,表示存在一条连接编号分别为 a,ba,b 的结点的无向边,结点编号范围从 11 到 nn 。

输出格式

输出两行,第 11 行判断图中各结点是否连通,若连通,则输出 YESYES ,否则输出 NONO 。 第 22 行输出两个连通的结点之间最短距离的最大值。

样例输入

复制代码
5 4
1 2
2 3
3 4
4 5

样例输出

复制代码
YES
4

说明

图中只有一个连通分量,必然是连通的,且两个连通的结点之间最短距离的最大值为 44 。

评测数据规模

对于 3030% 的评测数据,1≤n≤501≤n≤50, 1≤m≤1001≤m≤100 。

对于 5050% 的评测数据,1≤n≤2001≤n≤200, 1≤m≤100001≤m≤10000 。

对于 100100% 的评测数据,1≤n≤5001≤n≤500, 1≤m≤1051≤m≤105 。

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;


public class Main {

    static int N=510;     
       
    static int n,m;
    static int id=1;
    
    static int cnt=-1;
   
   
    static int f[][]=new int[N][N];
   
    
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
    
    public static void main(String[] args) throws IOException { 
    	
        StringTokenizer st=new StringTokenizer(br.readLine());
        n=Integer.parseInt(st.nextToken());  
        m=Integer.parseInt(st.nextToken());
    	
        for (int i = 0; i < N; i++) {
			Arrays.fill(f[i], Integer.MAX_VALUE);
			f[i][i]=0;
		}
        
       for (int i = 0; i < m; i++) {
    	   st=new StringTokenizer(br.readLine());
    	   int a=Integer.parseInt(st.nextToken()),b=Integer.parseInt(st.nextToken());
    	   f[a][b]=1;
    	   f[b][a]=1;
       }
       
       for (int k = 1; k <= n; k++) {
		  for (int i = 1; i <= n; i++) {
			 for (int j = 1; j <= n; j++) {
				if(f[i][k]!=Integer.MAX_VALUE && f[k][j]!=Integer.MAX_VALUE){
					f[i][j]=Math.min(f[i][j], f[i][k]+f[k][j]);
				}
			}
		  }
       }
       
       boolean connect=true;
       int res=Integer.MIN_VALUE;
       for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				if(f[i][j]==Integer.MAX_VALUE)connect=false;
				else res=Math.max(res, f[i][j]);
			}
       }
       if(connect){
    	   bw.write("YES\n");
       }else{
    	   bw.write("NO\n");
       }
       
       bw.write(res+"");
       
    	
        br.close();
        bw.flush();
        bw.close();
    }
    
    

       
}
相关推荐
hahaha60166 小时前
HLS高层次综合设计技巧--循环merge和循环split
人工智能·算法·计算机视觉
JAI科研6 小时前
Deepseek Agent Harness教程(七) | Deepseek Harness不是一个内核加一堆插件
开发语言·人工智能·深度学习·算法·自然语言处理·transformer·vllm
集思广益的灰太狼6 小时前
变频器启动致PLC数据异常?西门子G120配合滤波器EMC抑制方案
人工智能·算法·工控·emc·电磁兼容·变频器·西门子
方方洛6 小时前
vllm教程-03-架构设计
算法·架构
玄昌盛不会编程6 小时前
LeetCode——2091. 从数组中移除最大值和最小值
java·算法·leetcode
如何取名6 小时前
结合实际业务进行LRU淘汰算法优化设计(数据库开发日志)
数据库·算法
aichitang20246 小时前
快乐泛函每一天:希尔伯特空间中的最佳逼近与正交投影定理
人工智能·考研·算法·ai·面试·泛函分析
淬炼之火6 小时前
笔记:Visually-Guided Policy Optimization for Multimodal Reasoning
人工智能·笔记·算法·机器学习·语言模型·自然语言处理
一只QAQ7 小时前
c++项目
java·c++·算法
学习星球7 小时前
空天地一体化网络(NTN)深度解析:从Starlink D2C到3GPP NTN,卫星直连手机是如何实现的?
网络·人工智能·算法·智能手机·php