1. 程式人生 > >解題:SCOI 2008 天平

解題:SCOI 2008 天平

%s code tar pro blank space ret span closed

題面

我們很容易想到差分約束,但是我們建出來圖之後好像並不好下手,因為我們只能得到砝碼間的大小關系,並不能容易地得到每個砝碼的具體重量。

於是我們有了一種神奇的思路:既然得不到具體重量我們就不求具體重量了,只求出砝碼間的關系即可,因為砝碼只有三種還是可以討論的。具體來說我們用$maxx[i][j]$表示$i-j$的最大值,$mini[i][j]$表示$i-j$的最小值,然後跑Floyd得出砝碼間的關系,最後直接$n^2$枚舉砝碼檢查即可

技術分享圖片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4
using namespace std; 5 const int N=55,M=2550; 6 int maxx[N][N],mini[N][N]; 7 int n,a,b,cnt,ans1,ans2,ans3; 8 char rd[N]; 9 int main() 10 { 11 scanf("%d%d%d",&n,&a,&b); 12 for(int i=1;i<=n;i++) 13 { 14 scanf("%s",rd+1); 15 for(int j=1;j<=n;j++) 16 if
(rd[j]==+) maxx[i][j]=2,mini[i][j]=1; 17 else if(rd[j]==-) maxx[i][j]=-1,mini[i][j]=-2; 18 else if(rd[j]===||i==j) maxx[i][j]=mini[i][j]=0; 19 else maxx[i][j]=2,mini[i][j]=-2; 20 } 21 for(int k=1;k<=n;k++) 22 for(int i=1;i<=n;i++) 23 for
(int j=1;j<=n;j++) 24 if(i!=j&&i!=k&&j!=k) 25 { 26 maxx[i][j]=min(maxx[i][j],maxx[i][k]+maxx[k][j]); 27 mini[i][j]=max(mini[i][j],mini[i][k]+mini[k][j]); 28 } 29 for(int i=1;i<=n;i++) 30 if(i!=a&&i!=b) 31 for(int j=i+1;j<=n;j++) 32 if(j!=a&&j!=b) 33 { 34 ans1+=(mini[a][i]>maxx[j][b]||mini[a][j]>maxx[i][b]); 35 ans3+=(maxx[a][i]<mini[j][b]||maxx[a][j]<mini[i][b]); 36 ans2+=(maxx[a][i]==mini[a][i]&&maxx[j][b]==mini[j][b]&&maxx[a][i]==mini[j][b])|| 37 (maxx[a][j]==mini[a][j]&&maxx[i][b]==mini[i][b]&&maxx[a][j]==mini[i][b]); 38 } 39 printf("%d %d %d",ans1,ans2,ans3); 40 return 0; 41 }
View Code

解題:SCOI 2008 天平