HDU-3666 THE MATRIX PROBLEM(差分约束系统判断存在与否+特殊剪枝)
来源:互联网 发布:floyd算法伪代码 编辑:程序博客网 时间:2024/06/05 13:49
题意:
log(a[i]) - log(b[j]) >= L'
log(a[i]) - log(b[j]) <= R'
在网上看到两种优化,
(1)不必判断某一个点入队次数大于N,只要判断是否大于sqrt(1.0*N)。
(2)或者所有点的入队次数大于T*N,即存在负环,一般T取2。
其中,N为所有点的个数。
给一个N*M的矩阵,是否存在两列数a1,a2,a3...an 和 b1,b2.....bm使得对矩阵中的每个数进行下面的操作之后的值在[L,U]之间,操作为:a[i] * m[i][j] / b[j]。 N,M<=400
思路:
首先能得到式子 L <= c[ij]*a[i]/b[j] <= R,然后同时除以c[ij]得 L' <= a[i]/b[j] <= R',再取log我们就得到了两个不等式:log(a[i]) - log(b[j]) >= L'
log(a[i]) - log(b[j]) <= R'
由于a(i),b(j)都可取任何值,所以不必进行约束条件,至此所有约束条件用完了,于是建图差分约束即可。
在网上看到两种优化,
(1)不必判断某一个点入队次数大于N,只要判断是否大于sqrt(1.0*N)。
(2)或者所有点的入队次数大于T*N,即存在负环,一般T取2。
其中,N为所有点的个数。
但是,第二个优化在本题就用不了,第一个的正确性也不得而知,所以做题时先正常地>N,没办法再尝试这个优化。
代码:
#include <algorithm>#include <iostream>#include <string.h>#include <cstdio>#include <queue>#include <cmath>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 805;const int maxm = 160005*2;struct node{int v, next;double w;}edge[maxm];int no, head[maxn];int vis[maxn], cnt[maxn];double dis[maxn];queue<int> q;int N, M, L, R;inline void init(){no = 0;memset(head, -1, sizeof head);}inline void add(int u, int v, double w){edge[no].v = v; edge[no].w = w;edge[no].next = head[u]; head[u] = no++;}int SPFA(){memset(vis, 0, sizeof vis);fill(dis+1, dis+N+M+1, inf);memset(cnt, 0, sizeof cnt);while(!q.empty()) q.pop();dis[1] = 0;q.push(1); vis[1] = 1;while(!q.empty()){int u = q.front(); q.pop();vis[u] = 0; ++cnt[u];if(cnt[u] > sqrt(N+M)) return -1;for(int k = head[u]; k != -1; k = edge[k].next){int v = edge[k].v;if(dis[v] > dis[u]+edge[k].w){dis[v] = dis[u]+edge[k].w;if(!vis[v]) vis[v] = 1, q.push(v);}}}return 1;}int main(){//freopen("in.txt", "r", stdin);int x;while(~scanf("%d %d %d %d", &N, &M, &L, &R)){init();for(int i = 1; i <= N; ++i)for(int j = 1; j <= M; ++j){scanf("%d", &x);double _L = log(1.0*L/x);double _R = log(1.0*R/x);add(i, N+j, -_L);add(N+j, i, _R);}if(SPFA() != -1) puts("YES");else puts("NO");}return 0;}
差分约束:当题目中存在大于某数小于某数,求两个变量之间的至少值最多值,在大于小于约束条件下的成不成功存不存在,都要尝试考虑考虑差分约束!然后再尝试构建减法,除法通过取log构建减法,但加法和乘法貌似不可行,因为对第二个数取负会是什么意义?第二个数是为了代表一个点啊!不过某些题估计也可行,遇到题目再分析吧。
继续加油~
阅读全文
1 0
- HDU-3666 THE MATRIX PROBLEM(差分约束系统判断存在与否+特殊剪枝)
- HDU 3666 THE MATRIX PROBLEM 差分约束系统
- hdu 3666 THE MATRIX PROBLEM【差分约束系统】
- hdu 3666 THE MATRIX PROBLEM(差分约束系统)
- hdu 3666 THE MATRIX PROBLEM 差分约束系统
- hdu 3666 THE MATRIX PROBLEM (差分约束系统)
- HDU 3666 THE MATRIX PROBLEM (建图+差分约束+剪枝优化)
- hdu 3666 THE MATRIX PROBLEM 差分约束
- HDU 3666 THE MATRIX PROBLEM (差分约束判负环)
- HDU 3666 THE MATRIX PROBLEM 差分约束
- HDU 3666 THE MATRIX PROBLEM (差分约束判负环)
- HDU 3666 THE MATRIX PROBLEM 差分约束
- hdu 3666 THE MATRIX PROBLEM(差分约束,思路)
- HDU 3666 THE MATRIX PROBLEM(差分约束)
- Hdu 3666 THE MATRIX PROBLEM(差分约束)
- hdu 3666 THE MATRIX PROBLEM (差分约束)
- |hdu 3666|差分约束|THE MATRIX PROBLEM
- hdu3666 THE MATRIX PROBLEM --- 差分约束
- hdu3507Print Article(斜率)
- JZOJ 5234. 【NOIP2017模拟8.7A组】外星人的路径
- SQL的四种连接-左外连接、右外连接、内连接、全连接、交叉连接
- kickstart笔记
- Eclipse&&idea快捷键功能
- HDU-3666 THE MATRIX PROBLEM(差分约束系统判断存在与否+特殊剪枝)
- 51Nod
- 自己写个mock_server
- 实验吧-天网管理系统【php弱类型==与===的利用】
- 你不懂,哥的寂寞
- Python之re模块一
- nginx修改配置后reload原理初探
- props和state的区别
- Visible Lattice Points POJ