直接floyd求出传递闭包之后分类讨论就行了
dx[i][j]表示a[i]-a[j]的最大值
dn[i][j]表示a[i]-a[j]的最小值
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long dx[55][55],dn[55][55];
char s[55];
int n,A,B,C,D;
int main(){
cin>>n>>A>>B;
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=n;j++) {
if((s[j]=='=')||(i==j)){
dx[i][j]=dn[i][j]=0;
}
else if(s[j]=='-'){
dx[i][j]=-1;
dn[i][j]=-2;
}
else if(s[j]=='+'){
dx[i][j]=2;
dn[i][j]=1;
}else{
dx[i][j]=2;
dn[i][j]=-2;
}
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
if(i!=k){
for(int j=1;j<=n;j++){
if(j!=i&&j!=k){
if(dx[i][j]>dx[i][k]+dx[k][j]){
dx[i][j]=dx[i][k]+dx[k][j];
}
}
}
}
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
if(i!=k){
for(int j=1;j<=n;j++){
if(j!=i&&j!=k){
if(dn[i][j]<dn[i][k]+dn[k][j]){
dn[i][j]=dn[i][k]+dn[k][j];
}
}
}
}
}
}
int c1=0,c2=0,c3=0;
for(C=1;C<=n;C++){
if(C!=A&&C!=B){
for(D=1;D<C;D++){
if(D!=A&&D!=B){
if((dn[A][C]>dx[D][B])||(dn[B][C]>dx[D][A])){
c1++;
}
if((dx[C][A]==dn[C][A]&&dx[D][B]==dn[D][B]&&dn[C][A]+dn[D][B]==0)||
(dx[D][A]==dn[D][A]&&dx[C][B]==dn[C][B]&&dn[D][A]+dn[C][B]==0)){
c2++;
}
if((dn[C][A]>dx[B][D])||(dn[D][A]>dx[B][C])){
c3++;
}
}
}
}
}
cout<<c1<<" "<<c2<<" "<<c3<<endl;
return 0;
}