[多校2015.02.1006 高斯消元] hdu 5305 Friends
来源:互联网 发布:高拍仪软件电脑摄像头 编辑:程序博客网 时间:2024/06/16 09:38
题意:
给你n个人m条关系
每条关系包含a,b
代表a和b可以是线上朋友也可以是线下朋友
然后保证每个人的线上朋友数和线下朋友数相等
问你有多少种组成方法
思路:
官方题解是爆搜+剪枝,然而并不会写。。
比赛的时候想到用高斯消元来剪枝
最后枚举自由元
因为关系的话到了最后肯定有些关系是确定的。
这样一定会消掉一些部分
最后G++AC C++TLE。。
代码:
#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"using namespace std;int equ,var;int x[55],du[55];int a[55][55];int nofree_num;int gcd(int x,int y){ return y?gcd(y,x%y):x;}int lcm(int x,int y){ return x/gcd(x,y)*y;}void debug(){ for(int i=0; i<equ; i++) { for(int j=0; j<=var; j++) printf("%d ",a[i][j]); puts(""); } puts("");}int dfs(int p){ int ans=0; if(p<nofree_num) { int i,j; for(i=nofree_num-1; i>=0; i--) { int tep=a[i][var]; for(j=i+1; j<var; j++) tep=tep-(x[j]*a[i][j]); if(tep%a[i][i]!=0) return 0; x[i]=tep/a[i][i]; } for(i=0; i<equ; i++) if(x[i]!=1 && x[i]!=-1) return 0; return 1; } x[p]=-1; ans+=dfs(p-1); x[p]=1; ans+=dfs(p-1); return ans;}int gauss(){ int i,j,k; int row,col; for(row=0,col=0; row<equ&&col<var; row++,col++) { int maxr=row; for(i=row+1; i<equ; i++) if(abs(a[i][col])>abs(a[maxr][col])) maxr=i; if(a[maxr][col]==0) { row--; continue; } for(i=0; i<=var; i++) swap(a[row][i],a[maxr][i]); for(i=row+1; i<equ; i++) { if(a[i][col]) { int LCM=lcm(abs(a[row][col]),abs(a[i][col])); int ta=LCM/abs(a[row][col]); int tb=LCM/abs(a[i][col]); if(a[i][col]*a[row][col]<0) ta=-ta; for(j=col; j<=var; j++) a[i][j]=(a[i][j]*tb)-(a[row][j]*ta); } } } for(i=row; i<equ; i++) if(a[i][var]) return 0; for(i=0; i<equ; i++) { if(a[i][i]==0) { for(j=i+1; j<var; j++) if(a[i][j]) break; if(j==var) break; for(k=0; k<equ; k++) swap(a[k][i],a[k][j]); } } nofree_num=row; //debug(); if(var-nofree_num) { return dfs(var-1); } for(i=row-1; i>=0; i--) { int tep=a[i][var]; for(j=i+1; j<var; j++) tep=tep-(x[j]*a[i][j]); if(tep%a[i][i]!=0) return 0; x[i]=(tep/a[i][i]); if(x[i]!=1 && x[i]!=-1) return 0; } return 1;}int main(){ int t; cin>>t; while(t--) { int n,m; scanf("%d%d",&n,&m); equ=m; var=m; memset(a,0,sizeof(a)); memset(du,0,sizeof(du)); for(int i=0; i<m; i++) { int x,y; scanf("%d%d",&x,&y); du[x]++; du[y]++; a[x-1][i]=1; a[y-1][i]=1; } int ff=1; for(int i=1;i<=n;i++) { if(du[i]%2) { ff=0; break; } } if(ff==0) { puts("0"); continue; } // debug(); int ans=gauss(); printf("%d\n",ans); } return 0;}
0 0
- [多校2015.02.1006 高斯消元] hdu 5305 Friends
- HDU 5305 Friends (DFS)
- hdu 5305 Friends
- HDU 5305 Friends (DFS)
- hdu 5305 Friends 【暴搜】
- hdu 5305 friends
- HDU 5305 Friends
- HDU 5305 Friends
- HDU 5305 Friends
- HDU 5305 Friends(深搜)
- F - Friends-HDU 5305
- hdu 5305 Friends (dfs)
- HDU 5305(Friends-暴搜)
- HDU 5305 Friends DFS
- hdu 5305 Friends dfs
- HDU 5305 Friends
- HDU 5305 Friends(DFS)
- HDU 5305 Friends(dfs)
- 剑指Offer-->从上向下打印二叉树(★★)
- UVa 11401 Triangle Counting 数三角形
- Java基础语法(一)
- 怎样远程开机内网电脑?
- 【第二步】编程语言的学习
- [多校2015.02.1006 高斯消元] hdu 5305 Friends
- 图像处理------常见二值化方法汇总
- Java基础语法(二)
- 【转】前端工程师-新手必读
- Java基础语法(三)
- WdatePicker时间选择插件
- 重新开始
- Android USB Host的使用详解
- Darwin Streaming Server编译