您的位置:首页 > 其它

hdu 3666 THE MATRIX PROBLEM (差分约束)

2012-10-17 17:18 281 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3666

题意:给你一个N*M的矩阵,求两列数a1,a2,a3...an 和 b1,b2.....bm使得对矩阵中的每个数进行下面的操作之后的值在[L,U]之间,操作为:a[i] * m[i][j] / b[j]。 N,M<=400题解: 差分约束。

首先 L<= c[i][j] *ai / bj <= u ,以前 我们遇到的都是 减法的 差分约束 ,那么我们 只i要 取 log 就可以 了,两边 他同除以 c[i][j] , 然后取 log 锝 ,log(l) - log(c[i][j]) <= log(a) - log(b) <= log(u) - log(c[i][j]) ; 然后 SPFA 判断一下 是否 有 负环 即可。

1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-6
15 #define inf 10001000
16
17 #define ll __int64
18
19 #define read() freopen("data.txt","r",stdin) ;
20 #define inf 9999999
21 using namespace std;
22
23 const double pi = acos(-1.0);
24 const int maxn = 210;
25 #define N 1000
26
27
28 int n,m,vis
,num,head
;
29 int time
;//记录入队列的次数
30 int s,t ;
31 double dis
;
32 struct node
33 {
34 int next;
35 int v;
36 double w;
37 }p[N*N];
38
39 queue<int>que;
40 void add(int u,int v,double w)
41 {
42
43 p[num].v=v;
44 p[num].w=w;
45 p[num].next=head[u];
46 head[u]=num;
47 num++;
48 }
49
50 int SPFA()
51 {
52
53 memset(vis,0,sizeof(vis));
54 CL(time,0) ;
55 for(int i=0;i<=t;i++)dis[i]= inf;
56
57 dis[s] = 0;
58
59 while(!que.empty())que.pop();
60 que.push(s) ;
61 vis[s] = 1 ;
62
63 while(!que.empty())
64 {
65 int u=que.front();
66 vis[u]=0;
67 que.pop();
68 for(int i=head[u];i!=-1;i=p[i].next)
69 {
70 int v=p[i].v;
71 double w=p[i].w;
72 if(dis[v] > dis[u] + w)
73 {
74 dis[v] = dis[u]+w;
75 if(!vis[v])
76 {
77 vis[v]=1;
78 que.push(v);
79 time[v]++;
80 if(time[v]>(int)sqrt(t*1.0))return -1;// 含有回路
81 }
82 }
83 }
84 }
85 return 1;
86
87 }
88
89 int main()
90 {
91 int i , j , x,y,d,mx,a,b,mi,l,u;
92 double c ;
93 while(scanf("%d%d%d%d",&n,&m,&l,&u)!=EOF)
94 {
95 num = 0 ;
96 CL(head, -1) ;
97 double l1 = log(l*1.0) ;
98 double u1 = log(u*1.0) ;
99 for(i = 1; i <= n;i++)
{
for(j = 1 ; j <= m;j++)
{
scanf("%lf",&c) ;
double a = log(c);

add(i,j + n,a - l1);
add(j + n,i ,u1 - a) ;

}
}
s = 1;
t = m + n ;//因为 他图是联通的 所以 不用 加入 源点 ;

int f = SPFA();
if(f == 1)puts("YES");
else puts("NO") ;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: