3 3 1 6 2 3 4 8 2 6 5 2 9
YES
先开始就天真了。。我以为是贪心,而且仔细想了想还发现不了思路的漏洞
然后果断的WA。。后来我还是不太清楚为什么错误,于是找来AC代码,自己随机了100组测试数据
然后一个一个对拍,很惊奇的发现居然贪心只有很少的数据没有过。。
但是我仔细研究了下没有过的数据,最后还是发现,思维的漏洞
后来去看了下别人的解题报告。
别人说是用的差分约束。
我仔细想了想,发现这个题目虽然有不等式的存在,但是似乎并不好建图
再次翻阅解题报告,发现别人是利用对数。
因为对数可以把乘法变成+法,除法变成减法
这样图就非常好建立了
最后问有没有解可以直接判断负环
如果存在负环就输出NO,反之则输出YES
我的代码:
#include<stdio.h> #include<math.h> #include<string.h> #include<vector> #include<queue> #include<algorithm> #define inf 99999999 #define maxn 805 using namespace std; struct node { int v; double len; }; vector<node>map[maxn]; int n,m; void init() { int i; for(i=0;i<805;i++) map[i].clear(); } bool spfa(int s) { double dis[805]; int i,sum=0; queue<int>q; bool used[805]; int num[805]; memset(used,0,sizeof(used)); for(i=0;i<805;i++) dis[i]=inf; memset(num,0,sizeof(num)); dis[s]=0; used[s]=true; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); used[u]=false; for(i=0;i<map[u].size();i++) { node p=map[u][i]; if(dis[p.v]>dis[u]+p.len) { dis[p.v]=dis[u]+p.len; if(!used[p.v]) { used[p.v]=true; sum++; if(sum>2*(n+3*m)) return false; q.push(p.v); } } } } return true; } int main() { int i,j; double l,r,x; node p; while(scanf("%d%d%lf%lf",&n,&m,&l,&r)!=EOF) { init(); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%lf",&x); p.v=n+j; p.len=log(r/x); map[i].push_back(p); p.v=i; p.len=-log(l/x); map[n+j].push_back(p); } if(spfa(1)) printf("YES\n"); else printf("NO\n"); } return 0; }