这是一个简单的置换群
观察数据很重要,眼睛是个好东西。
只有1,2,3g三种。那就简单了。
差分约束嘛。
但是这个题的约束条件稍有不同,因为条件太少。
考虑上界和下界。
数据辣么小,floyd水过。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int dn[100][100]={0};
int dx[100][100]={0};
int n;
int A,B;
int main(){
//注意重量只有1,2,3三种。
scanf("%d%d%d",&n,&A,&B);
if(A<B){
swap(A,B);
}
// for(int i=1; i<=n; i++) {
// char s[200];
// 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 i=1;i<=n;i++){
char ch[100];
scanf("%s",ch);
for(int j=0;j<n;j++){
if((ch[j]=='=')||(j+1==i)){
dn[i][j+1]=0;
dx[i][j+1]=0;
}
else{
if(ch[j]=='-'){
dx[i][j+1]=-1;
dn[i][j+1]=-2;
}
else{
if(ch[j]=='+'){
dx[i][j+1]=2;
dn[i][j+1]=1;
}
else{
dx[i][j+1]=2;
dn[i][j+1]=-2;
}
}
}
}
}
// cout<<"working"<<endl;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++){
// cout<<dx[i][j]<<" ";
// }
// cout<<endl;
// }
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j||i==k||j==k)
continue;
dx[i][j]=min(dx[i][j],dx[i][k]+dx[k][j]);
dn[i][j]=max(dn[i][j],dn[i][k]+dn[k][j]);
}
}
}
// cout<<"working"<<endl;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++){
// cout<<dx[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<"----------"<<endl;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++){
// cout<<dn[i][j]<<" ";
// }
// cout<<endl;
// }
int c1=0;
int c2=0;
int c3=0;
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
if(i==A||i==B||j==A||j==B){
continue;
}
if(dn[A][i]>dx[j][B]||dn[B][i]>dx[j][A]){
c1++;
}
if(((dx[A][i]==dx[j][B])&&(dx[A][i]==dn[j][B])&&(dn[A][i]==dn[j][B]))||((dx[B][i]==dx[j][A])&&(dx[B][i]==dn[j][A])&&(dn[B][i]==dn[j][A]))){
c2++;
}
if((dx[B][i]<dn[j][A])||(dx[B][j]<dn[i][A])){
c3++;
}
}
}
cout<<c1<<" "<<c2<<" "<<c3;
}