题意化简就是让你模拟出两两题面喜欢的人数之间的大小关系,连接单向边,然后定义了S(s,t)代表从s到t的所有路径中,最小边的最大值。并输出对于点x,满足其他所有点y使得S(x,y)>=S(y,x)并输出这些点 (n<=500)
按题意模拟出建边后,对于该问题跑个Floryd,即可求出S数组,去转移式子S[x][y]=max(S[x][y],min(S[x][k],S[k][y]))
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int N=550,M=2e6+7;
int n,m;
int a[N][N];
int d[N][N];
int S[N][N];
bool vis[N];
bool VIS[N];
int num;
int Indeg[N],indeg[N];
vector<int>E[N];
queue<int>q;
vector<int >res;
void getd(int x,int y){
int A=0,B=0;
for(int i=1;i<=n;i++){
if(a[i][x]==a[i][y]) continue;
if(a[i][x]<a[i][y]){
if(a[i][x]) A++;
else B++;
}
else {
if(a[i][y]) B++;
else A++;
}
}
d[x][y]=A;
d[y][x]=B;
}
void dfs(int x){
vis[x]=true;
num++;
for(auto & it:E[x]){
indeg[it]++;
if(vis[it]) continue;
dfs(it);
}
}
void getS(int x){
memset(vis,false,sizeof(vis));
memset(VIS,false,sizeof(VIS));
for(int i=1;i<=m;i++) indeg[i]=0;
num=0;
dfs(x);
cout<<indeg[x]<<endl;
indeg[x]=0;
while(q.size()) q.pop();
q.push(x);
int s=x;
S[s][x]=550;
while(q.size()){
int x=q.front();
VIS[x]=true;
q.pop();
for(auto &y:E[x]){
S[s][y]=max(S[s][y],min(S[s][x],d[x][y]));
indeg[y]--;
if(indeg[y]==0){
q.push(y);
}
}
}
}
bool judge(int x){
for(int i=1;i<=m;i++) {
if(i==x) continue;
if(S[x][i]<S[i][x]) return false;
}
return true;
}
int main(){
//freopen(".txt","r",stdin);
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(int i=1;i<=m;i++){
for(int j=i+1;j<=m;j++){
getd(i,j);
if(d[i][j]>d[j][i]){
E[i].push_back(j);
S[i][j]=d[i][j];
}
else if(d[i][j]<d[j][i]){
E[j].push_back(i);
S[j][i]=d[j][i];
}
}
}
// for(int i=1;i<=m;i++){
// for(int j=1;j<=m;j++) {
// S[i][j]=d[i][j];
// }
// }
for(int k=1;k<=m;k++){
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
S[i][j]=max(S[i][j],min(S[i][k],S[k][j]));
}
}
}
// for(int i=1;i<=m;i++){
// for(int j=1;j<=m;j++) cout<<S[i][j]<<' ';
// cout<<endl;
// }
// for(int i=1;i<=m;i++){
// getS(i);
// }
for(int i=1;i<=m;i++){
if(judge(i)) res.push_back(i);
}
for(int i=0;i<res.size();i++){
printf("%d",res[i]);
if(i==(int)res.size()-1) puts("");
else printf(" ");
}
return 0;
}