HUST 1027 Enemy Target!
求二分图的最小点覆盖集,并输出
对于每一个a[i][j]=1,我们从行i-->列j建立一条边
显然,这张图是一张二分图。左边的节点代表删除哪一行,右边的节点代表删除哪一列。中间的边代表所有a[i][j]为1的点。
现在,我们需要做的事情就是找出最少的点,使这些点覆盖住所有的边(即删去哪几行哪几列,没有士兵)
最少的点,使这些点覆盖住所有的边 这个东西是最小点覆盖集。
对于一张二分图来说,在数量上,最小点覆盖集=最大匹配
如果 最大匹配>坦克数量,那么输出无解
剩下的情况就是有解了,如何寻找解?这问题困扰了我很久......最后还是看了别人的博客。
此外,这题目点最多有2000个,为什么匈牙利算法可以AC......不是o(n^3)效率的吗......
详见北京大学神犇Matrix67的讲解http://blog.csdn.net/niushuai666/article/details/7036897
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std; const int MAXN = + ;
int nx, ny;
int g[MAXN][MAXN];
int cx[MAXN], cy[MAXN];
int mk[MAXN];
int ROW, COLUMN, N;
char s[MAXN][MAXN];
vector<int>Gl[MAXN];
vector<int>Gr[MAXN];
vector<int> ansr;
vector<int> ansc;
int flagl[MAXN], flagr[MAXN];
int flag[MAXN];
int mat[MAXN][MAXN]; int path(int u)
{
for (int v = ; v<ny; v++)
{
if (g[u][v] && !mk[v])
{
mk[v] = ;
if (cy[v] == - || path(cy[v]))
{
cx[u] = v;
cy[v] = u;
return ;
}
}
}
return ;
} int MaxMatch()
{
int res = ;
memset(cx, -, sizeof(cx));
memset(cy, -, sizeof(cy));
for (int i = ; i<nx; i++)
{
if (cx[i] == -)
{
memset(mk, , sizeof(mk));
res = res + path(i);
}
}
return res;
} void dfs(int now, int x)
{
if (x==)
{
flagl[now] = ;
for (int i = ; i<Gl[now].size(); i++)
if (flagr[Gl[now][i]] == && cx[now] == Gl[now][i])
dfs(Gl[now][i], ); }
else
{
flagr[now] = ;
for (int i = ; i<Gr[now].size(); i++)
if (flagl[Gr[now][i]] == && cy[now] != Gr[now][i])
dfs(Gr[now][i], );
}
} int main()
{
while (~scanf("%d%d%d", &ROW, &COLUMN, &N))
{
for (int i = ; i < ROW; i++) scanf("%s", s[i]);
memset(g, , sizeof g);
for (int i = ; i<=ROW; i++) Gl[i].clear();
for (int i = ; i<=COLUMN; i++) Gr[i].clear();
for (int i = ; i < ROW; i++)
for (int j = ; j < COLUMN; j++)
if (s[i][j] == '')
{
g[i][j] = ;
Gl[i].push_back(j);
Gr[j].push_back(i);
}
nx = ROW;
ny = COLUMN;
int ans = MaxMatch();
if (ans>N) printf("NOT ENOUGH TANK\n");
else
{
printf("%d\n", ans); memset(flagl, , sizeof flagl);
memset(flagr, , sizeof flagr);
memset(flag, , sizeof flag);
memset(mat, , sizeof mat);
ansr.clear();
ansc.clear(); for (int i = ; i<ROW; i++) if (cx[i] != -) flag[cx[i]] = ;
for (int j = ; j<COLUMN; j++) if (!flag[j]) dfs(j, ); for (int i = ; i<ROW; i++) if (flagl[i]) ansr.push_back(i);
for (int i = ; i<COLUMN; i++) if (!flagr[i]) ansc.push_back(i); printf("ROW:");
for (int i = ; i < ansr.size(); i++) printf(" %d", ansr[i]+);
printf("\n"); printf("COLUMN:");
for (int i = ; i < ansc.size(); i++) printf(" %d", ansc[i]+);
printf("\n"); }
}
return ;
}
HUST 1027 Enemy Target!的更多相关文章
- Unity BehaviorDesigner行为树基础总结
BehaviorDesigner——行为树,用于控制和实现AI逻辑,类似于这样: 上面这个行为树实现了这样的逻辑: 当Player有Input时按照Input值来移动,无Input时查找最近的可攻击目 ...
- UVALive 7146 Defeat the Enemy(贪心+STL)(2014 Asia Shanghai Regional Contest)
Long long ago there is a strong tribe living on the earth. They always have wars and eonquer others. ...
- UVa 7146 Defeat the Enemy(贪心)
题目链接: 传送门 Defeat the Enemy Time Limit: 3000MS Memory Limit: 32768 KB Description Long long ago t ...
- Defeat the Enemy UVALive - 7146
Long long ago there is a strong tribe living on the earth. They always have wars and eonquer other ...
- UVA LIVE 7146 Defeat the Enemy
这个题跟codeforces 556 D Case of Fugitive思路一样 关于codeforces 556 D Case of Fugitive的做法的链接http://blog.csdn. ...
- UVALive 7146 Defeat The Enemy
Defeat The Enemy Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Long long ...
- Neither BindingResult nor plain target object for bean name 'command' available as request attribute
最近用JSR303在表单提交时使用Java Bean Validation验证数据.报错堆栈如下: java.lang.IllegalStateException: Neither BindingRe ...
- MySQL中You can't specify target table for update in FROM clause一场
mysql中You can't specify target table <tbl> for update in FROM clause错误的意思是说,不能先select出同一表中的某些值 ...
- jQuery之常用且重要方法梳理(target,arguments,slice,substring,data,trigger,Attr)-(一)
1.jquery data(name) data() 方法向被选元素附加数据,或者从被选元素获取数据. $("#btn1").click(function(){ $(" ...
随机推荐
- byte数组如何转为short数组 (转)
最近在搞毕业设计,做的是有关语音识别的手机应用.在处理音频的过程中,发现需要用short数组处理音频,可能光用byte会越界.但是java读文件没有一次性读到short数组中的api,要么是一个一个读 ...
- OpenGL—Android 开机动画源码分析一
.1 Android开机动画实现方式目前实现Android开机动画的方式主要是逐帧动画和OpenGL动画. ?逐帧动画 逐帧动画是一种常见的动画形式(Frame By Frame),其原理是在“连续的 ...
- ReactiveX序列——RxSwift 浅析
ReactiveX序列——RxSwift Swift是苹果公司新推出的一门现代化的编程语言,并且将其开源出来了,Swift具有很多的优点,这也使得这门语言推出的短时间引起了很大反应的原因,在最近的 ...
- [转]LayoutInflater的inflate函数用法
LayoutInflater作用是将layout的xml布局文件实例化为View类对象. 获取LayoutInflater的方法有如下三种: LayoutInflater inflater=(Layo ...
- JS定时器的使用--延时提示框
<title>无标题文档</title> <style> div{float:left;margin:10px;} #div1{width:50px; height ...
- Linux学习 -- 日志管理
日志服务 rsyslogd CentOS6 取代了原来的syslog rsyslogd 默认启动.自启动 常用命令:lastb.lastlog.last.w.who.users. 系统默认日志 和 ...
- $.ajax和$.post的区别(前者根据key-value/后者根据形参)
post不需要给key-value形式: $("#btn").click(function(){ var url=basePath+"/emp/login"; ...
- opencv 相关一个很好的博客
http://blog.csdn.net/zouxy09/article/category/1218765 图像卷积与滤波的一些知识点 图像卷积与滤波的一些知识点zouxy09@qq.comhttp: ...
- jquery获取页面相关尺寸
$(windows).width();获取页面可视宽度 $(windows).height();获取页面可视高度 $(document).height();获取页面内容的总高度 $(document) ...
- Win下安装Cygwin中的SSH服务
windows和linux各有其优越性,可以安装在同一台电脑上,但切换要重启.同时拥有两台电脑,一台装win,一台装linux,自然非常好,但具备此条件的不多.本文介绍cygwin,它可以让你在win ...