CF568D D. Sign Posts

CF568D D. Sign Posts

One Khanate had a lot of roads and very little wood. Riding along the roads was inconvenient, because the roads did not have road signs indicating the direction to important cities.

The Han decided that it’s time to fix the issue, and ordered to put signs on every road. The Minister of Transport has to do that, but he has only k signs. Help the minister to solve his problem, otherwise the poor guy can lose not only his position, but also his head.

More formally, every road in the Khanate is a line on the Oxy plane, given by an equation of the form Ax + By + C = 0 (A and B are not equal to 0 at the same time). You are required to determine whether you can put signs in at most k points so that each road had at least one sign installed.

Input

The input starts with two positive integers n, k (1 ≤ n ≤ 105, 1 ≤ k ≤ 5)

Next n lines contain three integers each, Ai, Bi, Ci, the coefficients of the equation that determines the road (|Ai|, |Bi|, |Ci| ≤ 105, Ai2 + Bi2 ≠ 0).

It is guaranteed that no two roads coincide.

Output

If there is no solution, print “NO” in the single line (without the quotes).

Otherwise, print in the first line “YES” (without the quotes).

In the second line print a single number m (m ≤ k) — the number of used signs. In the next m lines print the descriptions of their locations.

Description of a location of one sign is two integers v, u. If u and v are two distinct integers between 1 and n, we assume that sign is at the point of intersection of roads number v and u. If u =  - 1, and v is an integer between 1 and n, then the sign is on the road number v in the point not lying on any other road. In any other case the description of a sign will be assumed invalid and your answer will be considered incorrect. In case if v = u, or if v and u are the numbers of two non-intersecting roads, your answer will also be considered incorrect.

The roads are numbered starting from 1 in the order in which they follow in the input.

题意

给你n条直线,问是否纯在小于k个点使每条直线至少包含一个点。

思路

注意到k很小,考虑暴力枚举这k个交点,判断后续点是否包含这k个点即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct line{
	long long a,b,c;
}l[maxn];
struct data{
	int s[5][2];
	int num[5];
}o1,o;
int n,k;
bool samep(const line& u,const line& v,const line& w)
{
	if(v.a*w.b-v.b*w.a==0&&u.b*w.a-u.a*w.b==0) return false;
	if(u.c*(v.a*w.b-v.b*w.a)+v.c*(u.b*w.a-u.a*w.b)+w.c*(u.a*v.b-u.b*v.a)==0)return true;
	return false;
}
bool dfs(int now,data& ca)
{
	if(now==n+1) 
	{
		o=ca;
		return 1;
	}
	for(int i=0;i<k;i++)
	{
		data ne=ca;
		if(ne.num[i]!=2) ne.s[i][ne.num[i]++]=now;
		else if(!samep(l[ne.s[i][0]],l[ne.s[i][1]],l[now])) continue;
		if(dfs(now+1,ne)) return true;
	}
	return 0;
}
int main()
{
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&l[i].a,&l[i].b,&l[i].c);
	if(dfs(1,o1)) 
	{
		printf("YES\n");
		int ans=0;
		for(int i=0;i<k;i++) if(o.num[i]>0) ans++;
		printf("%d\n",ans);
		for(int i=0;i<ans;i++)
		{
			printf("%d ",o.s[i][0]);
			if(o.s[i][1]==0) printf("-1\n");
			else printf("%d\n",o.s[i][1]); 
		}
	}
	else printf("NO\n");
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值