THE MATRIX PROBLEM
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8855 Accepted Submission(s): 2281
Problem Description
You have been given a matrix C
N*M, each element E of C
N*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.
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 6 2 3 4 8 2 6 5 2 9
Sample Output
YES根据题意有L<=n[i][j]*a[i]/b[j]<=U; 即L/n[i][j]<=a[i]/b[j];a[i]/b[j]<=U/n[i][j]; 两边取对数,转化成减的形式: log(a[i])-log(b[j])>=log(L/n[i][j]); log(b[j])-log(a[i])>=-log(U/n[i][j]); 这样转化后就可以用差分约束系统求解,但是这里的log(a[i])是小数 为方便连边,把log(a[1])~log(n)看作是整数1~n; 把log(b[1])~log(b[m])看作是整数n+1~n+m; 这题还有特别鬼畜的一点,一开始用队列做的,一直超时,觉得自己解法 已经足够优化了,后来去查了别人的代码,是用栈做的,奇怪的是只是 把队列改成栈就节省了一半的时间,真不知道为什么。 #include<bits/stdc++.h> int n,m,L,U,anc[1002],tol,head[1002]; double d[1002]; bool vis[1002]; using namespace std; struct node { int to,next; double cost; }rode[400003]; void add(int a,int b,double c) { rode[tol].to=b; rode[tol].cost=c; rode[tol].next=head[a]; head[a]=tol++; } bool spfa() { int i,j; for(i=0;i<=1000;i++) d[i]=-1e9*1.0; memset(anc,0,sizeof(anc)); memset(vis,0,sizeof(vis)); stack<int>P; while(!P.empty())P.pop(); P.push(1);vis[1]=1;d[1]=0; while(!P.empty()) { int v=P.top();P.pop();vis[v]=0; for(i=head[v];i!=-1;i=rode[i].next) { node e=rode[i]; if(d[e.to]<d[v]+e.cost) { d[e.to]=d[v]+e.cost; if(!vis[e.to]) { P.push(e.to); vis[e.to]=1; anc[e.to]++; if(anc[e.to]>m+n)return 0; } } } } return 1; } int main() { while(~scanf("%d%d%d%d",&n,&m,&L,&U)) { int i,j;tol=0; memset(head,-1,sizeof(head)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { int x;scanf("%d",&x); add(j+n,i,log(1.00*L/x)); add(i,j+n,-log(1.00*U/x)); } if(spfa())printf("YES\n"); else printf("NO\n"); } return 0; }