【差分约束系统】【仍未AC】【Asia - Harbin - 2010/2011】【THE MATRIX PROBLEM】

【题目描述】You have been given a matrix CN x M, each element E of CN x 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$ \le$N, M$ \le$400, 1$ \le$L$ \le$U$ \le$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 6 
2 3 4 
8 2 6 
5 2 9

 

Sample Output

YES


【中文大意】给定一个矩阵,要求经过如下操作,使得每个元素在[L,U]这个范围内:第i行所有元素乘以ai,第j列所有元素除以bj。
如果存在满足这样条件的a1,a2,...,an;b1,b2,...,bn。则输出YES,否则输出NO

【个人体会】至今仍未AC,但是后来看了题解,算法是正确的,所以懒得调了。。。。TOT 经历了几个
小时的TLE+WA+RE,我无力了。。。

【题目解析】乘法除法可以用ln进行转换成加减法,对于第Aij个元素,需要满足限制条件ln(L)<=ln
(Aij)+ln(ai)-ln(bj)<=ln(U),将ai和bj看成点,建立边。判断是否存在负权回路,若存在输出
NO,不存在输出YES。

【代码】虽然没有AC,但还是贴出来。

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <vector>
 5 #include <deque>
 6 
 7 #define FILE_IO
 8 
 9 using namespace std;
10 
11 const int Maxn = 1000;
12 const double INF = 1e9;
13 
14 struct edge
15 {
16     int v; double c;
17     edge* next;
18     edge(int _v, double _c, edge* _next) : v(_v), c(_c), next(_next) {}
19 }* E[Maxn];
20 
21 bool hash[Maxn];
22 int N, M, Lim, Count[Maxn];
23 double L, U;
24 vector <double> Dist;
25 deque <int> Q;
26 
27 void Clear()
28 {
29     Q.clear();
30     for (int i = 0; i <= Lim; i ++) { E[i] = NULL; Count[i] = 0; }
31     memset(hash, 0, sizeof(hash));
32 }
33 
34 bool SPFA()
35 {
36     Dist.assign(Lim + 1, 0);
37     for (int i = 1; i <= Lim; i ++) { Q.push_back(i); hash[i] = true; }
38     while (Q.size())
39     {
40         int i = Q.front(); Q.pop_front(); hash[i] = false;
41         for (edge* j = E[i]; j; j = j -> next)
42         {
43             int v = j -> v;
44             if (Dist[i] + j -> c < Dist[v])
45             {
46                 Dist[v] = Dist[i] + j -> c;
47                 if (!hash[v])
48                 {
49                     hash[v] = true;
50                     Count[v] ++;
51                     if (Count[v] > Lim) return false;
52                     Q.push_back(v);
53                 }
54             }
55         }
56     }
57     return true;
58 }
59 
60 inline void edgeAdd(int x, int y, double c)
61 {
62     E[x] = new edge(y, c, E[x]);
63 }
64 
65 void Init()
66 {
67     Lim = N + M;
68     scanf("%lf%lf", &L, &U); L = log(L); U = log(U);
69     for (int i = 1; i <= N; i ++)
70         for (int j = 1; j <= M; j ++)
71         {
72             double c; scanf("%lf", &c);
73             c = log(c);
74             edgeAdd(N + j, i, U - c);
75             edgeAdd(i, N + j, c - L);
76         }
77 }
78 
79 int main()
80 {
81     #ifdef FILE_IO
82     //freopen("test.in", "r", stdin);
83     #endif // FILE_IO
84     while (scanf("%d%d", &N, &M) != EOF)
85     {
86         Init();
87         if (SPFA()) printf("YES\n");
88         else printf("NO\n");
89         Clear();
90     }
91     return 0;

 


 

posted on 2012-12-31 13:56  孤星ぁ紫辰  阅读(192)  评论(1编辑  收藏  举报

导航