hdoj 3666 THE MATRIX PROBLEM 【差分约束】

来源:互联网 发布:相关软件 编辑:程序博客网 时间:2024/05/24 01:53


THE MATRIX PROBLEM

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7410    Accepted Submission(s): 1896


Problem Description
You have been given a matrix CN*M, each element E of CN*M is positive and no more than 1000, The problem is that if there exist N numbers a1, a2, … an and M numbers b1, b2, …, bm, which satisfies that each elements in row-i multiplied with ai and each elements in column-j divided by bj, after this operation every element in this matrix is between L and U, L indicates the lowerbound and U indicates the upperbound of these elements.
 

Input
There are several test cases. You should process to the end of file.
Each case includes two parts, in part 1, there are four integers in one line, N,M,L,U, indicating the matrix has N rows and M columns, L is the lowerbound and U is the upperbound (1<=N、M<=400,1<=L<=U<=10000). In part 2, there are N lines, each line includes M integers, and they are the elements of the matrix.

 

Output
If there is a solution print "YES", else print "NO".
 

Sample Input
3 3 1 62 3 48 2 65 2 9
 

Sample Output
YES

题意:给出一个N*M矩阵,下界L以及上界U,问你存不存在序列a[1...N] 和 b[1...M],使得对矩阵里面的任一元素都有L <= Map[ i ][ j ] * a[ i ] / b[ j ] <= U 。存在输出YES,否则输出NO。

差分约束算法引子给出的是一系列未知数X1,X2,...Xn的不等式,让你求每个Xi(1 <= i <= n)的值。

和这道题很像吧?

思路:对于L <= Map[ i ][ j ] * a[ i ] / b[ j ] <= U 可转化为 log( L / Map[ i ][ j ] ) <= log( a[ i ] ) - log( b[ j ] ) <= log( U / Map[ i ][ j ]) 。log( a[ i ] ) 虚拟成 i 节点,log( b[ j ] ) 可以虚拟为 N + j节点。

上面条件的建图就不说了吧。。。

最后添加一个虚拟源点0,连通所有的点 ,给定一个权值0,因为点0是虚拟的,所以它和其它点间的关系不一定非要成立。 接下来就是最短路了。


#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <queue>#include <algorithm>#define MAXN 1000#define MAXM 400000+10#define INF 1000000using namespace std;struct Edge{int from, to;double val;int next;}edge[MAXM];double dist[MAXN];int head[MAXN], top;int used[MAXN];bool vis[MAXN];double Map[410][410];int N, M;double L, U;void init(){top = 0;memset(head, -1, sizeof(head));}void addEdge(int u, int v, double w){    edge[top].from = u;    edge[top].to = v;    edge[top].val = w;    edge[top].next = head[u];head[u] = top++;}void getMap(){for(int i = 1; i <= N; i++){for(int j = 1; j <= M; j++){scanf("%lf", &Map[i][j]);addEdge(N+j, i, log(U/Map[i][j]));addEdge(i, N+j, -log(L/Map[i][j]));}}for(int i = 1; i <= N+M; i++)//建立源点 0  加入差分约束系统addEdge(0, i, 0);}void SPFA(){//queue<int> Q;int S[MAXN]; int top = 0;for(int i = 0; i <= N+M; i++){dist[i] = i==0 ? 0 : INF;used[i] = i==0 ? 1 : 0;vis[i] = i==0 ? true : false;}S[top++] = 0;while(top){int u = S[--top];vis[u] = false;for(int i = head[u]; i != -1; i = edge[i].next){Edge E = edge[i];if(dist[E.to] > dist[u] + E.val){dist[E.to] = dist[u] + E.val;if(!vis[E.to]){vis[E.to] = true;used[E.to]++;if(used[E.to] > sqrt(N+M)){printf("NO\n");return ;}                    S[top++] = E.to;}}}}printf("YES\n");}int main(){while(scanf("%d%d%lf%lf", &N, &M, &L, &U) != EOF){init();getMap();SPFA();}return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 安许证三类人员不足了怎么办 考试准考证号写错了怎么办 科目一失约两次怎么办 钢筋送检两次不合格怎么办 公路原材料抽检不合格怎么办 混凝土回弹强度不合格怎么办 毕业证照片太丑怎么办 政审时找不到档案怎么办 劳动解除书开不出来怎么办 双流办健康证怎么办 户口本人数满了怎么办 二建有效期到了怎么办 二级建造师到期怎么办 网上选车牌号后怎么办 政府拖欠水利工程款怎么办 重庆造价员到期了怎么办 枕大神经发炎怎么办 塑钢推拉窗下沉怎么办 网上买东西数量不够怎么办 淘宝买东西数量不够怎么办 康佳遥控器坏了怎么办 电视机频幕脏了怎么办 极米遥控器失灵怎么办 电视遥控坏了怎么办 小米手机触摸屏失灵怎么办 oppo手机触摸屏失灵怎么办 苹果手机屏幕没反应怎么办 苹果6sp换屏卡顿怎么办 苹果4屏幕失灵怎么办 苹果手机老是卡怎么办 苹果手机卡机了怎么办 苹果手机卡屏了怎么办 苹果8手机老卡机怎么办 苹果手机不开机怎么办 手机开机后黑屏怎么办 苹果x手机黑屏怎么办 苹果7手机黑屏怎么办 苹果触控不灵敏怎么办 收银机触屏失灵怎么办 手机屏一半失灵怎么办 苹果六手机屏幕失灵怎么办