Hdu 3666(差分约束系统)

Hdu 3666

(1)思路:

将不等式化简L<=xij*(ai/bj)<=R

L/xij <= ai/bj <= R/xij

将两边开log

log(L) - log(xij) <= log(ai) - log(bj) <= log(R) -log (xij)

所以可以得到

db - da <= log(xij) - log(L)

da - db <= log(R) - log(xij)

所以更新得到最短路,判读是否存在环,如果存在环就不存在。

扫描二维码关注公众号,回复: 6534612 查看本文章

(2)代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 1e5+10;
const double INF = 1e9+10;
int vis[maxn],m,n,que[maxn<<2],tim[maxn],head[maxn],tot;
double dis[maxn],L,U;
struct Node{
	int v,nxt;
	double w;
}cur[maxn<<2];
void Init(){
	memset(head,-1,sizeof(head));
	tot = 0;
}
void Add(int x,int y,double z){
	cur[tot].v = y;
	cur[tot].nxt = head[x];
	cur[tot].w = z;
	head[x] = tot++;
}
bool spfa(){
	for(int i=1;i<=n+m;i++){
		vis[i] = 0;dis[i] = INF;tim[i] = 0;
	}
	dis[1] = 0;
	int top = 0;
	que[top++] = 1;tim[1]++;
	while(top!=0){
		int x = que[--top];vis[x] = 0;
		for(int i=head[x];i!=-1;i=cur[i].nxt){
			int y = cur[i].v;
			if(dis[y]>dis[x]+cur[i].w){
				dis[y] = dis[x]+cur[i].w;
				if(vis[y]==0){
					vis[y] = 1;
					que[top++] = y;
					if(++tim[y]>n+m+1) return false;
				}
			}
		}
	}
	return true;
}
int main(void){
	while(~scanf("%d%d%lf%lf",&n,&m,&L,&U)){
		Init();
		L = log2(L);U = log2(U);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				double tp;scanf("%lf",&tp);
				tp = log2(tp);
				int x = i,y = j+n;
				Add(x,y,tp-L);
				Add(y,x,U-tp);
			}
		}
		if(spfa()==true) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/92009506