POJ 3740 Easy Finding
2015-07-18 21:39
423 查看
DescriptionGiven a M× N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1.InputThere are multiple cases ended by EOF. Test case up to 500.The first line of input is M, N ( M ≤ 16, N ≤ 300). The next M lines every line contains N integers separated by space.OutputFor each test case, if you could find it output "Yes, I found it", otherwise output "It is impossible" per line.Sample Input
3 3 0 1 0 0 0 1 1 0 0 4 4 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0Sample Output
Yes, I found it It is impossible dfs+剪枝#include<cstdio> #include<iostream> #include<cstring> #include<map> #include<queue> #include<stack> #include<algorithm> #include<vector> #include<cmath> #include<string> using namespace std; const int maxn=305; int n,m,a[20][maxn],b[20][20],c[20],d[20],cnt; bool flag; void dfs(int x) { if (cnt==m) {flag=true; return;} if (flag||x>=n) return ; dfs(x+1); if (c[x]==0) { c[x]=1; int e[20]={0}; for (int i=0;i<n;i++) if (b[x][i]&&c[i]==0) {c[i]=1; e[i]=1;} cnt+=d[x]; dfs(x+1); for (int i=0;i<n;i++) if (e[i]) c[i]=0; c[x]=0; cnt-=d[x]; } } int main() { while (cin>>n>>m) { memset(b,0,sizeof(b)); memset(d,0,sizeof(d)); memset(c,0,sizeof(c)); for (int i=0;i<n;i++) for (int j=0;j<m;j++) scanf("%d",&a[i][j]); for (int i=0;i<n;i++) for (int j=0;j<m;j++) { if (a[i][j]) d[i]++; for (int k=i+1;k<n;k++) if (a[i][j]&&a[k][j]) b[i][k]=1; } flag=false; cnt=0; dfs(0); if (flag) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0; }dlx<pre name="code" class="cpp">#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll maxn=10005;int n,m;struct node{ int l,r,u,d; int x,y; node(int l=0,int r=0,int u=0,int d=0,int x=0,int y=0): l(l),r(r),u(u),d(d),x(x),y(y){}};struct DLX{ node e[maxn]; int n,sz,num; int ans[maxn],cnt[maxn]; void begin(int x) { sz=(n=x)+1; for (int i=0;i<=n;i++) { e[i]=node((i+n)%(n+1),(i+1)%(n+1),i,i,0,i); } memset(cnt,0,sizeof(cnt)); } void insert(int row) { int now=sz,x; for (int i=1;i<=n;i++) { scanf("%d",&x); if (x) { e[sz]=node(sz-1,sz+1,e[i].u,i,row,i); e[i].u=e[e[i].u].d=sz; cnt[i]++; sz++; } } if (sz>now) e[sz-1].r=now,e[now].l=sz-1; } void remove(int x) { e[e[x].l].r=e[x].r; e[e[x].r].l=e[x].l; for (int i=e[x].d;i!=x;i=e[i].d) for (int j=e[i].r;j!=i;j=e[j].r) { e[e[j].d].u=e[j].u; e[e[j].u].d=e[j].d; cnt[e[j].y]--; } } void resume(int x) { e[e[x].l].r=x; e[e[x].r].l=x; for (int i=e[x].d;i!=x;i=e[i].d) for (int j=e[i].r;j!=i;j=e[j].r) { e[e[j].d].u=j; e[e[j].u].d=j; cnt[e[j].y]++; } } bool dfs(int x) { if (!e[0].r){ num=x; return true;} int c=e[0].r; for (int i=e[0].r;i!=0;i=e[i].r) if (cnt[i]<cnt[c]) c=i; remove(c); for (int i=e[c].d;i!=c;i=e[i].d) { ans[x]=e[i].x; for (int j=e[i].r;j!=i;j=e[j].r) remove(e[j].y); if (dfs(x+1)) return true; for (int j=e[i].r;j!=i;j=e[j].r) resume(e[j].y); } resume(c); return false; } bool solve() { return dfs(0); }}dlx;int main(){ while (~scanf("%d%d",&n,&m)) { dlx.begin(m); for (int i=1;i<=n;i++) dlx.insert(i); if (dlx.solve()) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0;}
相关文章推荐
- 剑指off-反转链表
- Codeforces Gym 100187M M. Heaviside Function two pointer
- HDU 5284 wyh2000 and a string problem(字符串,水)
- UGO权限问题
- spring junit 做单元测试,报 Failed to load ApplicationContext 错误。
- POJ 2676 Sudoku
- NFS网络文件共享服务
- USACO Ski Course Design(枚举)
- 解题报告: 商品推荐走马灯
- CodeForces 402A
- iOS第三天认识及了解注意
- 函数返回引用的注意事项
- Enum类型
- 趁有空,再了解一下GROOVY中关于类的通例
- 坐标上升算法
- EM算法原理及证明
- Activity声明周期容易出现的问题
- 每天学习一点新东西——vim篇(二)
- swift2 枚举类型
- log4j:WARN Please initialize the log4j system properly解决办法