L2-044 大众情人 - java

L2-044 大众情人


Java (javac)
时间限制
1200 ms
内存限制
128 MB

其他编译器
时间限制
400 ms
内存限制
64 MB


题目描述:
请添加图片描述
人与人之间总有一点距离感。我们假定两个人之间的亲密程度跟他们之间的距离感成反比,并且距离感是单向的。例如小蓝对小红患了单相思,从小蓝的眼中看去,他和小红之间的距离为 1,只差一层窗户纸;但在小红的眼里,她和小蓝之间的距离为 108000,差了十万八千里…… 另外,我们进一步假定,距离感在认识的人之间是可传递的。例如小绿觉得自己跟小蓝之间的距离为 2,则即使小绿并不直接认识小红,我们也默认小绿早晚会认识小红,并且因为跟小蓝很亲近的关系,小绿会觉得自己跟小红之间的距离为 1+2=3。当然这带来一个问题,如果小绿本来也认识小红,或者他通过其他人也能认识小红,但通过不同渠道推导出来的距离感不一样,该怎么算呢?我们在这里做个简单定义,就将小绿对小红的距离感定义为所有推导出来的距离感的最小值。

一个人的异性缘不是由最喜欢他/她的那个异性决定的,而是由对他/她最无感的那个异性决定的。我们记一个人 i 在一个异性 j 眼中的距离感为 D i j D_{ij} Dij;将 i 的“异性缘”定义为 1 / m a x j ∈ S ( i ) { D i j } 1 / max_{ j \in S(i)} \{ D_{ij} \} 1/maxjS(i){Dij},其中 S(i) 是相对于 i 的所有异性的集合。那么“大众情人”就是异性缘最好(值最大)的那个人。

本题就请你从给定的一批人与人之间的距离感中分别找出两个性别中的“大众情人”。

输入格式:
输入在第一行中给出一个正整数 N(≤500),为总人数。于是我们默认所有人从 1 到 N 编号。

随后 N 行,第 i 行描述了编号为 i 的人与其他人的关系,格式为:

性别 K 朋友1:距离1 朋友2:距离2 …… 朋友K:距离K
其中 性别 是这个人的性别,F 表示女性,M 表示男性;K(<N 的非负整数)为这个人直接认识的朋友数;随后给出的是这 K 个朋友的编号、以及这个人对该朋友的距离感。距离感是不超过 1 0 6 10^{6} 106 的正整数。

题目保证给出的关系中一定两种性别的人都有,不会出现重复给出的关系,并且每个人的朋友中都不包含自己。

输出格式:
第一行给出自身为女性的“大众情人”的编号,第二行给出自身为男性的“大众情人”的编号。如果存在并列,则按编号递增的顺序输出所有。数字间以一个空格分隔,行首尾不得有多余空格。

输入样例:
6
F 1 4:1
F 2 1:3 4:10
F 2 4:2 2:2
M 2 5:1 3:2
M 2 2:2 6:2
M 2 3:1 2:5
输出样例:
2 3
4


给定n个人
性别 以及 每个人对k个人的距离感

求出女生和男生异性缘最好的人


emmmmmmm

先读题

一个人的异性缘不是由最喜欢他/她的那个异性决定的,而是由对他/她最无感的那个异性决定的

异 性 缘 = 1 m a x j ∈ S ( i ) { D i j } 异性缘 = \frac{1}{max_{j \in S(i) \{ D_{ij} \} }} =maxjS(i){Dij}1
也就是 i 到 j 的感觉距离中取最大值 组成 S(i)
        然后再在 S(i) 中 取最小值
        这样得到的值就会使最小的 也就是异性缘最好的

所以直接找男生女生中的最小感觉距离即可


为什么是最短路中呢?
因为题目中的
        如果小绿本来也认识小红,或者他通过其他人也能认识小红,但通过不同渠道推导出来的距离感不一样,该怎么算呢?我们在这里做个简单定义,就将小绿对小红的距离感定义为所有推导出来的距离感的最小值。
所以得知是最短路

如何求每个人到另一个人的感觉距离呢?
floyd


先求出每个人之间的感觉距离

然后再找出异性间的感觉距离 求出最远感觉距离得到数组S

然后找女生男生的最小值即可

然后再输出


import java.io.*;
import java.math.*;
import java.util.*;

public class Main
{
	static int inf = 0x3f3f3f3f;

	public static void main(String[] args) throws IOException
	{
		int n = Integer.valueOf(sc.readLine());

//		存储每个人对另一个人的感觉距离
		long map[][] = new long[n + 10][n + 10];
		for (int i = 1; i <= n; i++)
		{
			Arrays.fill(map[i], inf);
			map[i][i] = 0;
		}

//		存储是否为女生
		boolean sex[] = new boolean[n + 10];
		for (int a = 1; a <= n; a++)
		{
			String str[] = sc.readLine().split(" ");
			sex[a] = str[0].equals("F");

			int k = Integer.valueOf(str[1]);
			for (int i = 1; i <= k; i++)
			{
				String s[] = str[i + 1].split(":");
				int b = Integer.valueOf(s[0]), c = Integer.valueOf(s[1]);

//				当前 a 到 b 的感觉距离为 c 
				map[a][b] = c;
			}
		}

//		floyd 求每个人到另一个人的感觉距离
//		中间的踏板
//		也就是 i -> k -> j
		for (int k = 1; k <= n; k++)
		{
			for (int i = 1; i <= n; i++)
			{
				for (int j = 1; j <= n; j++)
				{
//					距离更小就替换
					if (map[i][j] > map[i][k] + map[k][j])
						map[i][j] = map[i][k] + map[k][j];
				}
			}
		}

//		S[i] 表示对第i个人的感觉距离最远的距离
		long S[] = new long[n + 10];

		long minF = inf, minM = inf;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
//				要为异性
				if (sex[i] != sex[j])
//					寻找最大的感觉距离
					S[i] = Math.max(S[i], map[j][i]);
			}
			if (sex[i])
				minF = Math.min(minF, S[i]);
			else
				minM = Math.min(minM, S[i]);
		}

//		输出异性缘最大的女生的
		int pos = 0;
		for (int i = 1; i <= n; i++)
		{
			if (sex[i] && minF == S[i])
			{
				if (pos++ > 0)
					out.print(" ");
				out.print(i);
			}
		}
		out.println();

//		输出异性缘最大的男生
		pos = 0;
		for (int i = 1; i <= n; i++)
		{
			if (!sex[i] && minM == S[i])
			{
				if (pos++ > 0)
					out.print(" ");
				out.print(i);
			}
		}

		out.flush();
		out.close();
	}

	static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(System.out);
}

fill
fill

split

equals

floyd
floyd
floyd


如果有说错的 或者 不懂的 尽管提 嘻嘻

一起进步!!!


闪现

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢谢 啊sir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值