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

本文介绍了一道关于矩阵操作的问题,通过适当的行乘列除操作使矩阵元素落在指定区间内,并采用SPFA算法判断解决方案的存在性。

【题目描述】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;

 


 

转载于:https://www.cnblogs.com/GXZC/archive/2012/12/31/2840540.html

['Asia/Aden', 'Asia/Almaty', 'Asia/Amman', 'Asia/Anadyr', 'Asia/Aqtau', 'Asia/Aqtobe', 'Asia/Ashgabat', 'Asia/Ashkhabad', 'Asia/Atyrau', 'Asia/Baghdad', 'Asia/Bahrain', 'Asia/Baku', 'Asia/Bangkok', 'Asia/Barnaul', 'Asia/Beirut', 'Asia/Bishkek', 'Asia/Brunei', 'Asia/Calcutta', 'Asia/Chita', 'Asia/Choibalsan', 'Asia/Chongqing', 'Asia/Chungking', 'Asia/Colombo', 'Asia/Dacca', 'Asia/Damascus', 'Asia/Dhaka', 'Asia/Dili', 'Asia/Dubai', 'Asia/Dushanbe', 'Asia/Famagusta', 'Asia/Gaza', 'Asia/Harbin', 'Asia/Hebron', 'Asia/Ho_Chi_Minh', 'Asia/Hong_Kong', 'Asia/Hovd', 'Asia/Irkutsk', 'Asia/Istanbul', 'Asia/Jakarta', 'Asia/Jayapura', 'Asia/Jerusalem', 'Asia/Kabul', 'Asia/Kamchatka', 'Asia/Karachi', 'Asia/Kashgar', 'Asia/Kathmandu', 'Asia/Katmandu', 'Asia/Khandyga', 'Asia/Kolkata', 'Asia/Krasnoyarsk', 'Asia/Kuala_Lumpur', 'Asia/Kuching', 'Asia/Kuwait', 'Asia/Macao', 'Asia/Macau', 'Asia/Magadan', 'Asia/Makassar', 'Asia/Manila', 'Asia/Muscat', 'Asia/Nicosia', 'Asia/Novokuznetsk', 'Asia/Novosibirsk', 'Asia/Omsk', 'Asia/Oral', 'Asia/Phnom_Penh', 'Asia/Pontianak', 'Asia/Pyongyang', 'Asia/Qatar', 'Asia/Qostanay', 'Asia/Qyzylorda', 'Asia/Rangoon', 'Asia/Riyadh', 'Asia/Saigon', 'Asia/Sakhalin', 'Asia/Samarkand', 'Asia/Seoul', 'Asia/Shanghai', 'Asia/Singapore', 'Asia/Srednekolymsk', 'Asia/Taipei', 'Asia/Tashkent', 'Asia/Tbilisi', 'Asia/Tehran', 'Asia/Tel_Aviv', 'Asia/Thimbu', 'Asia/Thimphu', 'Asia/Tokyo', 'Asia/Tomsk', 'Asia/Ujung_Pandang', 'Asia/Ulaanbaatar', 'Asia/Ulan_Bator', 'Asia/Urumqi', 'Asia/Ust-Nera', 'Asia/Vientiane', 'Asia/Vladivostok', 'Asia/Yakutsk', 'Asia/Yangon', 'Asia/Yekaterinburg', 'Asia/Yerevan']
02-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值