【图论】【二分图匹配】[HDU 2819]Swap
2015-07-28 15:24
435 查看
首先可以很容易的发现一个性质:无论怎么交换行和列,每一行每一列的元素数量始终不会改变,那么就像八皇后问题一样,只不过改成了棋盘上放了n个车不能互相冲突。那么每一个1的位置代表可以放一个车,每一个0的位置代表不能放车,那么可以发现如果在当前位置可以放个车并且放了的话,那么就不能在当前车的行和列上继续放车了,那么给行和列编号把有1的位置行和列连接起来,然后就做二分图匹配,因为是在棋盘上放车那么始终不会超过n个那么只需要看最大的匹配数量是否等于n就行了,那么方案怎么输出呢。首先可以发现如果当前可行,那么棋盘上一定放置了n个车不能互相冲突,那么肯定有n个并且每一行一个,那么只需要维护一下每一行的车的列数,然后和当前的行数比较如果不一样,就和当前行(i)的第i列交换,同时维护一下下面几行的在第i列的车改成在当前这个列就行了,然后保存下先输出次数,然后输出方案。
[code]#include <cstdio> #include <cstring> #include <algorithm> //#include <conio.h> #include <iostream> #include <vector> using namespace std; const int MAXN = 400; bool vis[MAXN+10]; int con[MAXN+10]; int endcnt; int n, m, k, Tcnt; struct node{ int v; node *next; }Edges[MAXN * MAXN * 2+10], *adj[MAXN+10], *ecnt=Edges; void addedge(int u, int v){ ++ecnt; ecnt->v = v; ecnt->next = adj[u]; adj[u] = ecnt; } bool dfs(int u){ for(node *p=adj[u];p;p=p->next){ if(!vis[p->v]){ vis[p->v] = true; if(con[p->v]==-1 || dfs(con[p->v])){ con[u] = p->v; con[p->v] = u; return true; } } } return false; } int ys[MAXN+5]; void work(){ int ret = 0; memset(con, -1, sizeof con); for(int i=endcnt;i>=1;i--) if(con[i] == -1){ memset(vis, 0, sizeof vis); ret += dfs(i); //if(ret == n) break; } if(ret == n){ vector<pair<int, int> > ans; int counter = 0; for(int i=1;i<=endcnt;i++) ys[i] = con[i] - n; for(int i=1;i<=n;i++){ if(ys[i] != i){ counter++; ans.push_back(make_pair(min(i, ys[i]), max(i, ys[i]))); for(int j=i+1; j<=n; j++){ if(ys[j] == i){ ys[j] = ys[i]; break; } } } } printf("%d\n", counter); for(int i=0;i<counter;i++) printf("C %d %d\n", ans[i].first, ans[i].second); } else printf("-1\n"); } bool read(){ int t1; if(scanf("%d", &n) == EOF) return false; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d", &t1); if(t1){ addedge(i, j+n); addedge(j+n, i); } } } endcnt=n; return true; } int main(){ while(read()){ work(); memset(adj, 0, sizeof adj); ecnt=Edges; } return 0; }
相关文章推荐
- 【bzoj3130】 SDOI2013费用流 最大流
- 比较Java Swing中三种注册事件的方法
- 创建fragment的适配器的时候,构造函数传入content参数
- HDU 1755--A Number Puzzle【next_permutation】
- GK110 Tesla K20最终规格:阉掉384个流处理器
- 杭电 2091 空心三角形
- sqlcmd的使用小结
- 命令行的基本使用方法(文件)
- 常用正则表达式 -- 费元星 java大神
- Node.Js —— PM2介绍
- Java中面向对象的详解
- Java学习笔记3:Java编程中字符串的处理
- VirtualBox安裝 Android-x86 4.4
- http及https了解
- 暑假的第一次测试(一)
- 当前市场上存在的针对数据库的解决方案
- 多重背包问题
- 问题-应用程序加载图标不可用
- 选出某一列不重复,某一列作为选择条件,其他列正常输出(摘抄)
- 命令行的基本使用方法(目录)