HDU 4305 Lightning (矩阵行列式求生成树个数+高斯逆元求行列式模板)
来源:互联网 发布:大小非农数据公布时间 编辑:程序博客网 时间:2024/05/21 06:28
Lightning
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 999 Accepted Submission(s): 333
Problem Description
There are N robots standing on the ground (Don't know why. Don't know how).
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.
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.
Input
There are several cases.
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.
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.
Output
One line for each case contains the answer.
Sample Input
33 2-1 00 11 03 2-1 00 01 03 1-1 00 11 0
Sample Output
31-1
Author
BUPT
Source
2012 Multi-University Training Contest 1
Recommend
zhuyuanchen520
思路:题意比较明显,就是求一张无向图的生成树的个数。
如何用矩阵行列式求生成树的个数,这里有比较详细的讲解:http://wtommy.ycool.com/post.2218850.html
之后这题就是判断3点共线情况和模板的问题了。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define N 301#define MOD 10007bool g[N][N];struct node{ int x,y;} p[N];int n,R;inline bool ok(int i,int j){ if((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)<=R*R) return 1; return 0;}int aa[N][N];int gauss(int r, int c){ bool flag = false; int coe = 1; int i=0, t=0; for(int j=0; j<c; ++j) { int index = i; for(int k=i; k<r; ++k) { if(aa[k][j] > 0) { index = k; break; } } if(aa[index][j]) { if(index != i) { for(int k=j; k<c; ++k) { swap(aa[i][k],aa[index][k]); } flag = !flag; } for(int k=i+1; k<r; ++k) { if(aa[k][j]) { coe = (coe * aa[i][j]) % MOD; ++ t; for(int l=c-1; l>=j; --l) { aa[k][l] = (aa[k][l] * aa[i][j] - aa[i][l] * aa[k][j]) % MOD; if(aa[k][l] < 0) { aa[k][l] += MOD; } } } } ++ i; } } for(i=1;i<MOD;++i) { if((coe * i) % MOD == 1) { break; } } int result = i; for(i=0; i<r; ++i) { result = (result * aa[i][i]) % MOD; } if(flag) { result = MOD - result; } return result;}inline int Direction(int i,int j,int k){ return (p[j].x-p[i].x)*(p[k].y-p[i].y)-(p[k].x-p[i].x)*(p[j].y-p[i].y);}inline bool On_Segment(int i,int j,int k){ if(p[k].x>=min(p[i].x,p[j].x)&&p[k].x<=max(p[i].x,p[j].x)&&p[k].y>=min(p[i].y,p[j].y)&&p[k].y<=max(p[i].y,p[j].y)) return 1; return 0;}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&R); memset(g,0,sizeof(g)); for(int i=1; i<=n; i++) scanf("%d%d",&p[i].x,&p[i].y); for(int i=1; i<=n; i++) for(int j=i+1; j<=n; j++) if(ok(i,j)) g[i][j]=g[j][i]=1; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(i!=k&&k!=j&&i!=j) if(Direction(i,j,k)==0&&On_Segment(i,j,k)) g[i][j]=g[j][i]=0; memset(aa,0,sizeof(aa)); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(g[i][j]) { aa[i-1][i-1]++; aa[j-1][j-1]++; aa[i-1][j-1]=aa[j-1][i-1]=-1; } for(int i=0;i<n-1;i++) for(int j=0;j<n-1;j++) aa[i][j]=aa[i+1][j+1]; int ans=gauss(n-1,n-1); if(ans==0) puts("-1"); else printf("%d\n",ans); } return 0;}
- HDU 4305 Lightning (矩阵行列式求生成树个数+高斯逆元求行列式模板)
- Hdu 4305 Lightning - 生成树计数 - 行列式求值
- HDU 4305 无向连通图的生成树个数 矩阵行列式取模
- 求矩阵行列式
- 求矩阵的行列式
- 矩阵求逆 转置 行列式
- 矩阵求逆 转置 行列式
- 求矩阵行列式的方法
- matlab如何求矩阵行列式
- det--求矩阵的行列式
- 【Codewars-求矩阵行列式】python
- 矩阵行列式
- 求行列式
- 行列式模板
- 矩阵求逆、转置、行列式(转)
- python实现矩阵求行列式的值
- matlab求矩阵特征值和特征向量、行列式
- 矩阵求逆及行列式求值
- 整数Hash的应用
- iOS应用程序状态切换相关
- 【Android】Android中 Paint 字体、粗细等属性的一些设置
- 在IIS(Internet 信息服务)中建立一个虚拟目录
- 【Android2.2及以上】如何允许你的应用移动到SD卡?
- HDU 4305 Lightning (矩阵行列式求生成树个数+高斯逆元求行列式模板)
- C 不常见的一些晦涩语法
- ExtJS在面向对象所作出的努力
- java.net.SocketException: Too many open files问题分析及解决方案
- 【Android】报表、线图、饼图、柱状图 (工具整理)
- 【Android UI设计与开发】第06期:底部菜单栏(一)使用TabActivity实现底部菜单栏
- javascript判断上传文件的大小,并给出提示
- 最全的 Twitter Bootstrap 开发资源清单
- Mac 下利用 FileMerge 进行代码合并教程