UVA - 10615 Rooks(二分图匹配 + 枚举)
来源:互联网 发布:lol美服账号淘宝购买 编辑:程序博客网 时间:2024/06/05 09:12
题目大意:给出一个N*N的棋盘,上面放了一些车。现在要用尽量少的颜色对这些车进行染色,使得同一行同一列的任意两个车的颜色不同
解题思路:首先,先统计一下需要染多少种颜色。
需要染多少种颜色,是由一行或者一列的车的最大数量决定的。
接着枚举一下每种颜色(假设颜色为k种),再决定哪些地方需要染哪些颜色,决定哪些地方染哪些颜色,这就由二分图匹配来决定了
首先,先建立这个二分图。如何建立这个二分图呢,将所有车的位置(i,j),i和j连线
但是所有的车的位置(i,j)都连线了,在k次的枚举下,并不能每次都能二分图完美匹配,因为每次都完美匹配都需要n条匹配边,而所提供的连线并不能保证有
所以我们得提供一下一些多余的线,使得每次都能完美匹配
那么如何提供多余的线呢,首先我们可以记录一下每行每列在车的连线上已经有多少个了
因为要有k次完美匹配,所以每行每列被连的次数必须等于k,所以现在的任务就是将这些未满k的行和列进行连边就可以了,这样就可以保证每次都是完美匹配了
然后在完美匹配的情况下,再考虑所匹配的这个点是不是车就可以了
#include <cstdio>#include <cstring>#include <vector>using namespace std;#define N 110int n, MaxColor;int color[N][N], link[N], inRow[N], inCol[N];char map[N][N];bool vis[N];vector<int> G[N];void init() { memset(inRow, 0, sizeof(inRow)); memset(inCol, 0, sizeof(inCol)); MaxColor = 0; scanf("%d", &n); for (int i = 0; i < n; i++) { G[i].clear(); scanf("%s", map[i]); for (int j = 0; j < n; j++) { if (map[i][j] == '*') { inRow[i]++, inCol[j]++; G[i].push_back(j); } } } for (int i = 0; i < n; i++) MaxColor = max(MaxColor, max(inRow[i], inCol[i])); for (int i = 0; i < n; i++) if (inRow[i] < MaxColor) for (int j = 0; j < n && inRow[i] < MaxColor; j++) { while (inRow[i] < MaxColor && inCol[j] < MaxColor) { inRow[i]++; inCol[j]++; G[i].push_back(j); } }}bool dfs(int u) { for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (!vis[v]) { vis[v] = true; if (!(~link[v]) || dfs(link[v])) { link[v] = u; return true; } } } return false;}void hungary() { memset(link, -1, sizeof(link)); for (int i = 0; i < n; i++) { memset(vis, 0, sizeof(vis)); dfs(i); }}void solve() { memset(color, 0, sizeof(color)); int cnt = 0; while (cnt < MaxColor) { ++cnt; hungary(); for (int i = 0; i < n; i++) { int row = link[i]; if (map[row][i] == '*') color[row][i] = cnt; for (int j = 0; j < G[row].size(); j++) if (G[row][j] == i) { G[row].erase(G[row].begin() + j); break; } } } printf("%d\n", MaxColor); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (j) printf(" "); printf("%d", color[i][j]); } printf("\n"); }}int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0;}
0 0
- UVA - 10615 Rooks(二分图匹配 + 枚举)
- [UVA 10615]Rooks[二分图匹配]
- Uva 10615 Rooks(二分图匹配)
- UVA 10615 Rooks <二分图 + 正则二分图 + 完全匹配>
- Uva 10615 Rooks(二分图完美匹配+补边)
- UVa live6525Attacking rooks(二分最大匹配之最大匹配)
- (intermediate) 二分图(边着色) UVA 10615 Rooks
- uva 10615 - Rooks(完美匹配)
- UVALive 6525 Attacking rooks(二分图最大匹配)
- hnu 13028 Attacking rooks(二分图匹配 匈牙利算法)
- Uva-10615-Rooks
- UVA 10615 Rooks(?)
- 【二分匹配】 UVALive 6525 Attacking rooks
- LA 6525 Attacking rooks 二分匹配
- 二分图多重匹配+二分枚举-poj2112
- poj 3343 二分图匹配+二分枚举
- UVa 二分图匹配 Examples
- UVa 二分图匹配 Biginners
- NodeJs学习(一) 环境搭建
- IOS UIAutomation (xcode 6)
- Spherical Harmonics Lighting in DirectX
- Hbuilder开发app实战-识岁03-文件上传
- Windows平台使用RMAN命令自动删除Oracle过期归档日志的方法
- UVA - 10615 Rooks(二分图匹配 + 枚举)
- 三种凹凸材质算法总结
- 项目风险的理解
- 8.21总结
- Ubuntu下搭建tftp服务器最简单方法
- android SDK 国内更新方法
- 在现有工程中创建XCTest到工程
- Android学习之基于隐式的Intent的通讯
- Java静态绑定与动态绑定