反思: 水题,赛场上捣鼓了一个小时最后还是没捣鼓出来,打完队友和我说是单向边,我就有点懵,没想到赛后补题把双向边改成单向边就从5分变成了25分,读题不仔细,爆零两行泪啊啊。开头题目就说了距离感是单向的,自己一看样例看懂了就没再读前面自己觉得是废话的文字,哎,引以为戒。
题目链接:
题意:
思路:
初始化两两之间的距离为无穷大,之后根据样例输入建立单向边,并将男性和女性分别存到两个vector中,样例大小为500,直接跑一遍floyd就能确定人与人之间认为的距离最小值。
之后枚举每个人,对于这个人我们要找的是所有异性对这个人距离的最大值,遍历完所有异性后得到的最终最大值越小,异性缘就越大,所以这个地方也没必要再让1/最大值,在所有同性中找到1/最大值 最大的,其实也就是找最大值最小的。
样例:
输入
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
代码:
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=500+10;
int dis[N][N];//dis[i][j]为i对j的距离感
int n;
bool sex[N];//true为male
vector<int> male,bm;
vector<int> female,bfm;
int md=inf,fmd=inf;
vector<int> tmp;
int main(){
scanf("%d",&n);
char ch;
int y,kn,d;
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=n;i++){
cin>>ch;
scanf("%d",&kn);
if(ch=='M'){
sex[i]=true;
male.push_back(i);
}
else{
sex[i]=false;
female.push_back(i);
}
for(int j=1;j<=kn;j++){
scanf("%d:%d",&y,&d);
dis[i][y]=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]);
}
int ma;
for(int i=1;i<=n;i++){
ma=0;
if(sex[i]){
for(auto it:female){
int j=it;
if(ma<dis[j][i]){
ma=dis[j][i];
}
}
if(ma<md){
md=ma;
bm.clear();
bm.push_back(i);
}
else if(ma==md){
bm.push_back(i);
}
}
else{
for(auto it:male){
int j=it;
if(ma<dis[j][i]){
ma=dis[j][i];
}
}
if(ma<fmd){
fmd=ma;
bfm.clear();
bfm.push_back(i);
}
else if(ma==fmd){
bfm.push_back(i);
}
}
}
for(int i=0;i<bfm.size();i++){
if(i)
printf(" ");
printf("%d",bfm[i]);
}
printf("\n");
for(int i=0;i<bm.size();i++){
if(i)
printf(" ");
printf("%d",bm[i]);
}
}