HDU 4305 Lightning(计算几何,判断点在线段上,生成树计数)
Lightning
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1099 Accepted Submission(s): 363

Suddenly the sky turns into gray, and lightning storm comes! Unfortunately, one of the robots is stuck by the lightning!

So it becomes overladen. Once a robot becomes overladen, it will spread lightning to the near one.
The spreading happens when:
Robot A is overladen but robot B not.
The Distance between robot A and robot B is no longer than R.
No other robots stand in a line between them.
In this condition, robot B becomes overladen.
We assume that no two spreading happens at a same time and no two robots stand at a same position.

The problem is: How many kind of lightning shape if all robots is overladen? The answer can be very large so we output the answer modulo 10007. If some of the robots cannot be overladen, just output -1.
The first line is an integer T (T < = 20), indicate the test cases.
For each case, the first line contains integer N ( 1 < = N < = 300 ) and R ( 0 < = R < = 20000 ), indicate there stand N robots; following N lines, each contains two integers ( x, y ) ( -10000 < = x, y < = 10000 ), indicate the position of the robot.
3 2
-1 0
0 1
1 0
3 2
-1 0
0 0
1 0
3 1
-1 0
0 1
1 0
1
-1
首先是根据两点的距离不大于R,而且中间没有点建立一个图。
之后就是求生成树计数了。
Matrix-Tree定理(Kirchhoff矩阵-树定理)。Matrix-Tree定理是解决生成树计数问题最有力的武器之一。它首先于1847年被Kirchhoff证明。在介绍定理之前,我们首先明确几个概念:
1、G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数。
2、G的邻接矩阵A[G]也是一个n*n的矩阵, 并且满足:如果vi、vj之间有边直接相连,则aij=1,否则为0。
我们定义G的Kirchhoff矩阵(也称为拉普拉斯算子)C[G]为C[G]=D[G]-A[G],则Matrix-Tree定理可以描述为:G的所有不同的生成树的个数等于其Kirchhoff矩阵C[G]任何一个n-1阶主子式的行列式的绝对值。所谓n-1阶主子式,就是对于r(1≤r≤n),将C[G]的第r行、第r列同时去掉后得到的新矩阵,用Cr[G]表示。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <list>
#include <string>
#include <math.h>
using namespace std; struct Point
{
int x,y;
Point(int _x = ,int _y = )
{
x = _x,y = _y;
}
Point operator - (const Point &b)const
{
return Point(x-b.x,y-b.y);
}
int operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
void input()
{
scanf("%d%d",&x,&y);
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;
e = _e;
}
};
bool onSeg(Point P,Line L)
{
return
((L.s-P)^(L.e-P)) == &&
(P.x-L.s.x)*(P.x-L.e.x) <= &&
(P.y-L.s.y)*(P.y-L.e.y) <= ;
}
int sqdis(Point a,Point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
} const int MOD = ;
int INV[MOD];
//求ax = 1( mod m) 的x值,就是逆元(0<a<m)
long long inv(long long a,long long m)
{
if(a == )return ;
return inv(m%a,m)*(m-m/a)%m;
}
struct Matrix
{
int mat[][];
void init()
{
memset(mat,,sizeof(mat));
}
int det(int n)//求行列式的值模上MOD,需要使用逆元
{
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
mat[i][j] = (mat[i][j]%MOD+MOD)%MOD;
int res = ;
for(int i = ;i < n;i++)
{
for(int j = i;j < n;j++)
if(mat[j][i]!=)
{
for(int k = i;k < n;k++)
swap(mat[i][k],mat[j][k]);
if(i != j)
res = (-res+MOD)%MOD;
break;
}
if(mat[i][i] == )
{
res = -;//不存在(也就是行列式值为0)
break;
}
for(int j = i+;j < n;j++)
{
//int mut = (mat[j][i]*INV[mat[i][i]])%MOD;//打表逆元
int mut = (mat[j][i]*inv(mat[i][i],MOD))%MOD;
for(int k = i;k < n;k++)
mat[j][k] = (mat[j][k]-(mat[i][k]*mut)%MOD+MOD)%MOD;
}
res = (res * mat[i][i])%MOD;
}
return res;
}
}; Point p[];
int n,R;
bool check(int k1,int k2)//判断两点的距离小于等于R,而且中间没有点阻隔
{
if(sqdis(p[k1],p[k2]) > R*R)return false;
for(int i = ;i < n;i++)
if(i!=k1 && i!=k2)
if(onSeg(p[i],Line(p[k1],p[k2])))
return false;
return true;
}
int g[][];
int main()
{
//预处理逆元
for(int i = ;i < MOD;i++)
INV[i] = inv(i,MOD);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&R);
for(int i = ;i < n;i++)
p[i].input();
memset(g,,sizeof(g));
for(int i = ;i < n;i++)
for(int j = i+;j <n;j++)
if(check(i,j))
g[i][j] = g[j][i] = ;
Matrix ret;
ret.init();
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
if(i != j && g[i][j])
{
ret.mat[i][j] = -;
ret.mat[i][i]++;
}
printf("%d\n",ret.det(n-));
}
return ;
}
HDU 4305 Lightning(计算几何,判断点在线段上,生成树计数)的更多相关文章
- HDU - 4305 - Lightning 生成树计数 + 叉积判断三点共线
HDU - 4305 题意: 比较裸的一道生成树计数问题,构造Krichhoof矩阵,求解行列式即可.但是这道题还有一个限制,就是给定的坐标中,两点连线中不能有其他的点,否则这两点就不能连接.枚举点, ...
- hdu 1086(计算几何入门题——计算线段交点个数)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2 ...
- POJ-2318 TOYS 计算几何 判断点在线段的位置
题目链接:https://cn.vjudge.net/problem/POJ-2318 题意 在一个矩形内,给出n-1条线段,把矩形分成n快四边形 问某些点在那个四边形内 思路 二分+判断点与位置关系 ...
- HDU 4305 Lightning Matrix Tree定理
题目链接:https://vjudge.net/problem/HDU-4305 解法:首先是根据两点的距离不大于R,而且中间没有点建立一个图.之后就是求生成树计数了. Matrix-Tree定理(K ...
- POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内
首先判断是不是凸多边形 然后判断圆是否在凸多边形内 不知道给出的点是顺时针还是逆时针,所以用判断是否在多边形内的模板,不用是否在凸多边形内的模板 POJ 1584 A Round Peg in a G ...
- HDU4305:Lightning(生成树计数+判断点是否在线段上)
Lightning Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)
Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...
- hdu 4643 GSM 计算几何 - 点线关系
/* hdu 4643 GSM 计算几何 - 点线关系 N个城市,任意两个城市之间都有沿他们之间直线的铁路 M个基站 问从城市A到城市B需要切换几次基站 当从基站a切换到基站b时,切换的地点就是ab的 ...
- hdu acm 1166 敌兵布阵 (线段树)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
随机推荐
- 如何掌握jQuery插件开发(高能)
在实际开发工作中,总会碰到像滚动,分页,日历等展示效果的业务需求,对于接触过jQuery以及熟悉jQuery使用的人来说,首先想到的肯定是寻找现有的jQuery插件来满足相应的展示需求.目前页面中常用 ...
- 关于IE8版本提示“不支持‘trim’此属性或者方法”的解决办法。转摘雨网络
在js文件的前面加 String.prototype.trim = function () { return Trim(this); }; function LTrim(str) { var i; f ...
- Network——物理层-练习题与解答
1. 无线电天线通常在其直径等于无线电波的波长的情况下工作效果最好.合理的天线直径的范围是从1厘米到5米.问所覆盖的频率范围是怎样的? 解答: λf = c , c=3x108 (m/s) 对于λ=1 ...
- finally
finally 我们都知道无论try语句中是否抛出异常,finally中的语句一定会被执行.我们来看下面的例子: try: f = open("/tmp/output", &qu ...
- ELK日志处理
ELK的工作原理: 使用多播进行机器发现同一个集群内的节点,并汇总各个节点的返回组成一个集群,主节点要读取各个节点的状态,在关键时候进行数据的恢复,主节点会坚持各个节点的状态,并决定每个分片的位置,通 ...
- Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up
http://mail-archives.apache.org/mod_mbox/cloudstack-users/201306.mbox/%3c201306181058330006472@gmail ...
- Apache配置基于端口号的虚拟主机 Apache virtual host configuration is based on the port
有可能只有一个ip出口,但却有多个项目,那么就需要基于端口号架设虚拟主机. Step 1: 检查是否开启 httpd-vhosts.conf apache/conf/httpd.conf文件 # Vi ...
- SpringMVC调用过程
SpringMVC中的四大组件: 1.前端控制器(DispatcherServlet) =>[无需程序员开发] 主要是负责request和response对象的转发和响应. 2.处理器 ...
- magento后台语言
Magento后台自身携带了一个语言切换的功能,见后台左下角 你会发现长长的一串,其中绝大多数语言你可能根本没有机会用到,而你想要从中文切换到英文时,每次都要瞪大眼睛去找英文在下拉框的哪个位置,所以精 ...
- gvim 编辑器配置
"关才兼容模式 set nocompatible "模仿快捷键,如:ctrt+A 全选.Ctrl+C复制. Ctrl+V 粘贴等 source $VIMRUNTIME/vimrc_ ...