【差分约束系统】【仍未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 (1N, M400, 1LU10000). 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;