题意:
n种化妆品,m个顾客,每个顾客对每款化妆品有一个非负的评级。评级越小表示越喜欢。若评级为零,表示最讨厌。
d(x,y)表示在化妆品x和y中,更喜欢x的人数
对于一个序列C1,C2,……Ck,其中d(C_i,C_i+1)>d(C_i+1,C_i)定义偏爱程度为最小的d(C_i,C_i+1)
S(x,y)表示所有以x为开头,以y为结尾的序列中,偏爱程度最大值
若一个化妆品x满足S(x,y)>=S(y,x)对于所有的y(y!=x)都成立,则该化妆品是最好的
求出所有的最好的化妆品
暴力求出所有的d,若d(i,j)>d(j,i),i向j连一条权值为d(i,j)的 边
s(x,y)为所有从x到y的路径最小值的最大值
floyd更新,s(x,y)=max[ s(x,y),min(s(x,k),s(k,y)) ]
#include<cstdio> #include<algorithm> using namespace std; #define N 501 int a[N]; int d[N][N]; int ans[N]; int main() { int n,m,x; scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { for(int j=1;j<=n;++j) { scanf("%d",&a[j]); if(!a[j]) a[j]=1e7; } for(int j=1;j<n;++j) for(int k=j+1;k<=n;++k) if(a[j]<a[k]) d[j][k]++; else if(a[k]<a[j]) d[k][j]++; } for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) if(d[i][j]<d[j][i]) d[i][j]=0; else if(d[i][j]>d[j][i]) d[j][i]=0; else d[i][j]=d[j][i]=0; for(int k=1;k<=n;++k) for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) d[i][j]=max(d[i][j],min(d[i][k],d[k][j])); /*for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) printf("%d ",d[i][j]); printf(" "); }*/ bool tag; x=0; for(int i=1;i<=n;++i) { tag=true; for(int j=1;j<=n && tag;++j) { if(i==j) continue; if(d[i][j]<d[j][i]) tag=false; } if(tag) ans[++x]=i; } sort(ans+1,ans+x+1); for(int i=1;i<=x;++i) printf("%d ",ans[i]); }