#差分约束,Floyd#洛谷 2474 [SCOI2008]天平

题目


分析

非传统差分约束??
注意只有结果保证惟一的选法才统计在内
这就为差分约束提供了依据
以左边重为例,假设现在选择的砝码为\(i,j\)
那么\(\because A+B>i+j\therefore A-i>j-B\)
既然结果保证唯一,那么也就是\(min(A-i)>max(j-B)\)
右边重同理,也就是\(max(A-i)<min(j-B)\)
同样重也很显然,就是
\(min(A-i)=max(A-i),min(j-B)=max(j-B),max(A-i)=min(j-B)\)
讲到这里该怎么做,floyd现身了,考虑维护最短路和最长路,

  1. 等号也就是\(i-j\leq 0,i-j\geq 0\)
  2. 大于号也就是\(i-j\leq -1,i-j\geq -2\)
  3. 小于号也就是\(i-j\leq 2,i-j\geq 1\)
  4. 问号也就是\(i-j\geq -2,i-j\leq 2\)

按照这个floyd建图分别跑最短路和最长路即可
这和传统的SPFA有什么区别呢,可以发现它求的是多源最短路,
那么Floyd要比SPFA更加方便


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=51; char s[N];
int n,A,B,dmn[N][N],dmx[N][N],ans1,ans2,ans3;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
signed main(){
	scanf("%d%d%d",&n,&A,&B);
	for (rr int i=1;i<=n;++i){
	    scanf("%s",s+1),s[i]='=';
	    for (rr int j=1;j<=n;++j)
	    switch (s[j]){
	    	case '=':{
	    		dmn[i][j]=0,dmx[i][j]=0;
				break;
			}
			case '+':{
				dmn[i][j]=1,dmx[i][j]=2;
				break;
			}
			case '-':{
				dmn[i][j]=-2,dmx[i][j]=-1;
				break;
			}
			case '?':{
				dmn[i][j]=-2,dmx[i][j]=2;
				break;
			}
		}
	}
	for (rr int k=1;k<=n;++k)
	for (rr int i=1;i<=n;++i)
	for (rr int j=1;j<=n;++j)
	if ((i^k)&&(i^j)&&(k^j))
		dmn[i][j]=max(dmn[i][j],dmn[i][k]+dmn[k][j]),//下界
		    dmx[i][j]=min(dmx[i][j],dmx[i][k]+dmx[k][j]);//上界
	for (rr int i=1;i<=n;++i)
	for (rr int j=1;j<i;++j)
	if ((i^j)&&(i^A)&&(i^B)&&(j^A)&&(j^B)){
		if (dmn[A][i]>dmx[j][B]||dmn[B][i]>dmx[j][A]) ++ans1;
		if (dmn[i][A]>dmx[B][j]||dmn[i][B]>dmx[A][j]) ++ans3;
		if ((dmn[A][i]==dmx[A][i]&&dmn[j][B]==dmx[j][B]&&dmn[A][i]==dmx[j][B])||
		    (dmn[A][j]==dmx[A][j]&&dmn[i][B]==dmx[i][B]&&dmn[A][j]==dmx[i][B]))
		    ++ans2;
	}
	return !printf("%d %d %d",ans1,ans2,ans3);
} 
posted @ 2020-11-04 21:05  lemondinosaur  阅读(55)  评论(0编辑  收藏  举报