现在的位置: 首页 > 综合 > 正文

HDU/HDOJ 3666 差分约束 2010 Asia Regional Harbin

2017年11月23日 ⁄ 综合 ⁄ 共 2215字 ⁄ 字号 评论关闭

 

THE MATRIX PROBLEM

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3000    Accepted Submission(s): 783

Problem Description
You have been given a matrix CN*M, each element E of CN*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.

 

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
 

Source
 

先开始就天真了。。我以为是贪心,而且仔细想了想还发现不了思路的漏洞

然后果断的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;
}

 

抱歉!评论已关闭.