求二分图的最小点覆盖集,并输出

对于每一个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!的更多相关文章

  1. Unity BehaviorDesigner行为树基础总结

    BehaviorDesigner——行为树,用于控制和实现AI逻辑,类似于这样: 上面这个行为树实现了这样的逻辑: 当Player有Input时按照Input值来移动,无Input时查找最近的可攻击目 ...

  2. 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. ...

  3. UVa 7146 Defeat the Enemy(贪心)

    题目链接: 传送门 Defeat the Enemy Time Limit: 3000MS     Memory Limit: 32768 KB Description Long long ago t ...

  4. Defeat the Enemy UVALive - 7146

      Long long ago there is a strong tribe living on the earth. They always have wars and eonquer other ...

  5. UVA LIVE 7146 Defeat the Enemy

    这个题跟codeforces 556 D Case of Fugitive思路一样 关于codeforces 556 D Case of Fugitive的做法的链接http://blog.csdn. ...

  6. UVALive 7146 Defeat The Enemy

    Defeat The Enemy Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Long long ...

  7. Neither BindingResult nor plain target object for bean name 'command' available as request attribute

    最近用JSR303在表单提交时使用Java Bean Validation验证数据.报错堆栈如下: java.lang.IllegalStateException: Neither BindingRe ...

  8. 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出同一表中的某些值 ...

  9. jQuery之常用且重要方法梳理(target,arguments,slice,substring,data,trigger,Attr)-(一)

    1.jquery  data(name) data() 方法向被选元素附加数据,或者从被选元素获取数据. $("#btn1").click(function(){ $(" ...

随机推荐

  1. table详解

    1.tr 元素定义表格行,th 元素定义表头,td 元素定义表格单元. tr内是th还是td可由自己定义,th,td可存在于任一行,th与td的区别在与th字体更粗 2.定义一个table默认有bor ...

  2. Windsock套接字I/O模型学习 --- 第三章

    1. WSAAsyncSelect 模型 WSAAsyncSelect 模型比较简单,是为了适应Windows的消息驱动环境而设置的,WSAAsyncSelect 函数自动把套接字设为非阻塞模式.MF ...

  3. Linux下安装php开发框架yaf

    yaf框架中文手册:http://yaf.laruence.com/manual/index.html yaf手册:http://www.php.net/manual/en/book.yaf.php ...

  4. 新手引导-ugui

    http://www.unitymanual.com/thread-38287-1-1.html 我已经在 干货区发布了,所以 这里就记录一下地址,懒得再贴了 新年第一贴,大家 看完代码 ,是不是发现 ...

  5. HDOJ--ACM-Steps--2.1.3--Cake(GCD,简单数学)

    一次生日Party可能有p人或者q人参加,现准备有一个大蛋糕.问最少要将蛋糕切成多少块(每块大小不一定相等),才能使p人或者q人出席的任何一种情况,都能平均将蛋糕分食. Input 每行有两个数p和q ...

  6. 学习笔记——组合模式Composite

    组合模式,典型的层次结构. 与装饰器类图相似. 区别在于:装饰器模式是为了在接口中增加方法,而组合模式在于层次元素的叠加. ConcreteComponent就是中间结点,可以包含更多的Concret ...

  7. HDU 2609 How many

    最小表示法+Map或者字典树,最小表示法找了个模板,还没学习呢... #include<cstdio> #include<cstring> #include<cmath& ...

  8. linux下执行scrapy的爬虫定时任务

    刚开始执行scrapy crawl zentaos可以完成扫描 但是通过linux的crontab任务,只执行了连接mongodb的操作,并创建了索引 也就是说scrapy crawl zentaos ...

  9. 移动端touch点穿(穿透)解决办法

    回答一 穿透(点穿)是在mobile各种浏览器上发生的常见的bug.可能是由click事件的延迟或者事件冒泡导致. 移动web开发常用的Zepto库中的touch和tap事件就会有点穿的bug(Zep ...

  10. 一个web项目在myeclipse中add deployment时无法被识别出来的原因

    当我们一个web项目,在myeclipse中,add deployment时,可能发现,根本无法被识别成web项目,可能的原因有:   1. 项目的properties ->Myeclipse ...