> 文章列表 > L2-044 大众情人「最短路」

L2-044 大众情人「最短路」

L2-044 大众情人「最短路」

L2-044 大众情人

题目描述:

n个人,有向图,有男女性别之分,我们定义异性缘为11到n中所有异性到i的距离最大值\\frac{1}{1到n中所有异性到i的距离的最大值}1n中所有异性到i的距离的最大值1

分别输出女性和男性中异性缘最好的人的下标,如果某种性别的异性缘最好的人存在多个,则从小到大输出下标,末行不允许有空格
明明几句话就能说明白的事情,非得写成文言文恶心人是吧

思路:

首先利用Floyd暴力求解每个人之间的最短距离dis[i][j]dis[i][j]dis[i][j]

对于每个人i,我们枚举j,找到dis[j][i]dis[j][i]dis[j][i]最大的异性,让ans[i]=dis[j][i]ans[i]=dis[j][i]ans[i]=dis[j][i]

再对于两个性别分别枚举,找到最大值,存下来输出即可

不过这个题数据范围绝对有误,说保证距离感是不超过1e6的正整数,一共才500个点,最大也就499*1e6 = 5e8左右,我上届开成1e9不给过,开再大点才给过,cynmslcynmslcynmsl,数据都不会造,下次别出了

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MAX 300050
int n, m, x;
int dis[505][505];
char sex[500];int ans[505];
void work()
{int num1 = 0, num2 = 0;cin >>n;memset(dis, 0x3f, sizeof(dis));int k;for(int i = 1; i <= n; ++i){dis[i][i] = 0;cin >> sex[i] >>k;if(sex[i] == 'F')++num1;else ++num2;while(k--){int j, d;scanf("%d:%d", &j, &d);dis[i][j] = d;}}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 i = 1; i <= n; ++i){for(int j = 1; j <= n; ++j){if(sex[i] != sex[j]){ans[i] = max(ans[i], dis[j][i]);}}}int m1 = 2e9, m2 = 2e9;for(int i = 1; i <= n; ++i){if(sex[i] == 'F')m1 = min(m1, ans[i]);else m2 = min(m2, ans[i]);}vector<int>v;for(int i = 1; i <= n; ++i){if(sex[i] == 'F' && ans[i] == m1)v.push_back(i);}for(int i = 0; i < v.size();++i)cout << v[i] <<" \\n"[i==v.size()-1];v.clear();for(int i = 1; i <= n; ++i){if(sex[i] == 'M' && ans[i] == m2)v.push_back(i);}for(int i = 0; i < v.size();++i)cout << v[i] <<" \\n"[i==v.size()-1];
}int main()
{work();return 0;
}