题目链接:http://poj.org/problem?id=3084

本题主要在构图上,我采用的是把要保护的房间与源点相连,有intruder的与汇点相连,相对麻烦。

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector> #define maxn 30
#define maxe 5000
using namespace std; const int INF = 0x3f3f3f; struct Edge{
int from,to,cap,flow;
int next;
}; struct Dinic{
int s,t;
int head[maxn];
int cur[maxn];
Edge edges[maxe];
int d[maxn];
bool vis[maxn];
int cnt; void init(){
memset(head,-,sizeof(head));
cnt = ;
}
void addedge(int from,int to,int cap){
edges[cnt].from = from; edges[cnt].to = to; edges[cnt].cap = cap;
edges[cnt].flow = ; edges[cnt].next = head[from]; head[from] = cnt++;
edges[cnt].from = to ; edges[cnt].to = from; edges[cnt].cap = ;
edges[cnt].flow = ; edges[cnt].next = head[to]; head[to] = cnt++;
}
bool bfs(){
memset(vis,,sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = true;
d[s] = ;
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i=head[u];i!=-;i=edges[i].next){
Edge& e = edges[i];
if(!vis[e.to] && e.cap>e.flow){
vis[e.to] = true;
d[e.to] = d[e.from] + ;
Q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int u,int res){
if( u == t || res == ) return res;
int flow = ,f;
for(int& i=cur[u];i!=-;i=edges[i].next){ //还不是很理解到cur[]的作用;
Edge& e = edges[i];
if(d[e.to] == d[e.from] + && (f = dfs(e.to,min(res,e.cap-e.flow)))>){
e.flow += f;
edges[i^].flow -= f;
flow += f;
res -= f;
if(res == ) break;
}
}
return flow;
}
int Maxflow(int S,int T){
s = S; t = T;
int flow = ;
while(bfs()){
for(int i=s;i<=t;i++) cur[i] = head[i];
flow += dfs(s,INF);
}
return flow;
}
}solver; int main()
{
//if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);}
int T;
cin>>T;
while(T--){
solver.init();
int m,n;
scanf("%d%d",&m,&n);
n++;
int s,t;
s = ; t = m+;
solver.addedge(s,n,INF);
for(int i=;i<=m;i++){
char ch[];
int adjnum;
scanf("%s%d",ch,&adjnum);
if(ch[] == 'I'){
//printf("i %d\n",i);
solver.addedge(i,t,INF);
for(int j=;j<=adjnum;j++){
int a;
scanf("%d",&a);
a++;
solver.addedge(a,t,INF); //能从intruder所在房间到达的房间要与汇点相连 }
}
else{
for(int j=;j<=adjnum;j++){
int a;
scanf("%d",&a);
a++;
if(a == n) solver.addedge(s,i,INF); //能到达保护房间也要与源点相连;
solver.addedge(i,a,);
solver.addedge(a,i,INF); //这是一直WA的地方;
}
}
}
int ans = solver.Maxflow(s,t);
if(ans >= INF) printf("PANIC ROOM BREACH\n");
else printf("%d\n",ans);
}
}

另一种构图,简单多了

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector> #define maxn 30
#define maxe 5000
using namespace std; const int INF = 0x3f3f3f; struct Edge{
int from,to,cap,flow;
int next;
}; struct Dinic{
int s,t;
int head[maxn];
int cur[maxn];
Edge edges[maxe];
int d[maxn];
bool vis[maxn];
int cnt; void init(){
memset(head,-,sizeof(head));
cnt = ;
}
void addedge(int from,int to,int cap){
edges[cnt].from = from; edges[cnt].to = to; edges[cnt].cap = cap;
edges[cnt].flow = ; edges[cnt].next = head[from]; head[from] = cnt++;
edges[cnt].from = to ; edges[cnt].to = from; edges[cnt].cap = ;
edges[cnt].flow = ; edges[cnt].next = head[to]; head[to] = cnt++;
}
bool bfs(){
memset(vis,,sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = true;
d[s] = ;
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i=head[u];i!=-;i=edges[i].next){
Edge& e = edges[i];
if(!vis[e.to] && e.cap>e.flow){
vis[e.to] = true;
d[e.to] = d[e.from] + ;
Q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int u,int res){
if( u == t || res == ) return res;
int flow = ,f;
for(int& i=cur[u];i!=-;i=edges[i].next){ //还不是很理解到cur[]的作用;
Edge& e = edges[i];
if(d[e.to] == d[e.from] + && (f = dfs(e.to,min(res,e.cap-e.flow)))>){
e.flow += f;
edges[i^].flow -= f;
flow += f;
res -= f;
if(res == ) break;
}
}
return flow;
}
int Maxflow(int S,int T){
s = S; t = T;
int flow = ;
while(bfs()){
for(int i=s;i<=t;i++) cur[i] = head[i];
flow += dfs(s,INF);
}
return flow;
}
}solver; int main()
{
//if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);}
int T;
cin>>T;
while(T--){
solver.init();
int m,n;
scanf("%d%d",&m,&n);
n++;
int s,t;
s = ; t = m+;
solver.addedge(n,t,INF);
for(int i=;i<=m;i++){
char ch[];
int adjnum;
scanf("%s%d",ch,&adjnum);
if(ch[] == 'I'){
solver.addedge(s,i,INF);
} for(int j=;j<=adjnum;j++){
int a;
scanf("%d",&a);
a++;
solver.addedge(i,a,INF);
solver.addedge(a,i,);
}
}
int ans = solver.Maxflow(s,t);
if(ans >= INF) printf("PANIC ROOM BREACH\n");
else printf("%d\n",ans);
}
}

poj 3084 最小割的更多相关文章

  1. poj 2125(最小割)

    题目链接:http://poj.org/problem?id=2125 思路:将最小点权覆盖转化为最小割模型,于是拆点建图,将点i拆成i,i+n,其中vs与i相连,边容量为w[i]-,i+n与vt相连 ...

  2. poj 3204(最小割--关键割边)

    Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7 ...

  3. POJ 3469 最小割 Dual Core CPU

    题意: 一个双核CPU上运行N个模块,每个模块在两个核上运行的费用分别为Ai和Bi. 同时,有M对模块需要进行数据交换,如果这两个模块不在同一个核上运行需要额外花费. 求运行N个模块的最小费用. 分析 ...

  4. 网络流 poj 3308 最小割

    t个样例 n*m的矩阵 L个伞兵 给出每行每列装激光的花费 伞兵的位置 要求杀死所有伞兵 总费用为这些费用的乘积  求花费最小 建图  源点 ->   行   -> 列  -> 汇点 ...

  5. poj 3469 最小割模板sap+gap+弧优化

    /*以核心1为源点,以核心2为汇点建图,跑一遍最大流*/ #include<stdio.h> #include<string.h> #include<queue> ...

  6. poj 3084(最小割)

    题目链接:http://poj.org/problem?id=3084 思路:题目的意思是不让入侵者进入保护的房间,至少需要锁几道门.网络流建模:设一个超级源点,源点与有入侵者的房间相连,边容量为in ...

  7. POJ 3084 Panic Room (最小割建模)

    [题意]理解了半天--大意就是,有一些房间,初始时某些房间之间有一些门,并且这些门是打开的,也就是可以来回走动的,但是这些门是确切属于某个房间的,也就是说如果要锁门,则只有在那个房间里才能锁. 现在一 ...

  8. POJ 3308 Paratroopers(最小割EK(邻接表&矩阵))

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

  9. poj 1815 Friendship 字典序最小+最小割

    题目链接:http://poj.org/problem?id=1815 In modern society, each person has his own friends. Since all th ...

随机推荐

  1. VS中监视窗口,即时窗口和输出窗口的使用

    一.监视窗口 1.配置应用程序,使应用程序处于调试状态. 2.点击“调试”----“窗口”----“监视”----“监视1”,打开监视窗口. 3.在监视窗口中“名称”栏中输入变量名称或html元素id ...

  2. vs2010安装路径解决不能修改的方法

    环境:win7 64位 解决:网上说需要卸载以下4项 Microsoft Visual Studio Tools for Applications 2.0 - ENU Microsoft Visual ...

  3. directsound 应用实例

    sdk里边有个文件夹Samples\C++\XInput\AudioController这个就是

  4. ios开发之通知事件

    每天学习一点点,总结一点点,成功从良好的习惯开始! 昨天学习了ios开发中的关于通知事件的一些东西,在这里简单总结下,仅供初学者学习,更多的是怕我自己忘了,咩哈哈~~~~ 通知(notificatio ...

  5. git extrad_addons 部署说明

    注册一个git账号 : 网址:  https://github.com/ 1:安装git   sudo apt-get install git 2:  b把urc扩展占模块pull下来    cd   ...

  6. HTML DOM(一):认识DOM

     分类: HTML/JavaScript/CSS(10)  版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/ghsau. 什么是DOM?       通过 Jav ...

  7. 应用SVN(CentOS中搭建SVN服务器)

    简单介绍如何在虚拟机 CentOS 中,搭建 SVN 服务器. 软件版本信息 Vmware 10.0.0 build-1295980 CentOS 7.0-1406-x64 Java 1.7.0_67 ...

  8. WM_SIZE和WM_MOVE的函数体内容为什么不一样?

    搞不懂,要想一想- procedure TWinControl.WMSize(var Message: TWMSize); begin UpdateBounds; // 类函数 inherited; ...

  9. 执行计划中常见index访问方式(转)

    近期有朋友对于单个表上的index各种情况比较模糊,这里对于单个表上,单个index出现的大多数情况进行了总结性测试,给出了测试结果,至于为什么出现这样的试验结果未做过多解释,给读者留下思考的空间.本 ...

  10. Linxu安装Lamp环境

    安装MySQL数据库 sudo apt-get install mysql-server mysql-client 下图为提示输入数据库密码,然后回车,之后还有提示,再重复输入一次,再回车 最后安装完 ...