题目链接: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. VS2015升级Update2之后Cordova程序提示:此应用程序无法在此电脑上运行

    VS2015在升级到Update2之后,有可能出现如下异常,在运行Cordova项目时提示: 查看输出面板会有乱码错误信息: 出现此问题的原因是在于npm程序损坏了.vs调用的npm程序并不是在nod ...

  2. basicAnimation移动图形

    目的:采用CABasicAnimation  点击屏幕上的点来是实现图像的位置移动  并且位置能够不反弹 难点:1 通过动画的KeyPath找到layer的属性 2 通过NSValue将点包装成对象 ...

  3. c#wiform中KeyDown事件

    当首次按下键盘上某个键时发生事件. 例如 private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Ke ...

  4. spring data jpa Specification 例子

    /** * 封装查询条件 * * @param baseQueryDTO * @return */ private Specification<ActivityBase> getSpeci ...

  5. Spring 实例化bean的方式

    实例化bean的方式有三种: 1.用构造器来实例化 2.使用静态工厂方法实例化 3.使用实例工厂方法实例化 当采用构造器来创建bean实例时,Spring对class并没有特殊的要求, 我们通常使用的 ...

  6. SGU 196.Matrix Multiplication

    时间限制:0.25s 空间限制:4M Solution n=10000,m=100000,显然不能用矩阵乘法乘出来. S= ATA 对于矩阵S的一行,所有在A矩阵中1位置的元素都相等,并且都等于这一行 ...

  7. WPF WebBrowser 不可见问题的解析[转]

    问题概述: 1.在Xaml中加入WebBrowser(不论是WPF中的控件,还是Winform中的控件) 2.设置Window Background="Transparent" A ...

  8. this详解:JAVASCRIPT中的this到底是谁?

    语法 this 全局对象 在全局执行上下文(函数之外),this引用的是全局对象. console.log(this.document === document); // true // In web ...

  9. 史上最强NDK入门项目实战

    目标: 利用NDK生成SO库,使用SO库进行JNI调用,在Android sdcard创建文件并写入数据. 工具: NDK1.5 R1, android SDK1.5 R1, SDCARD, Ecli ...

  10. C缩写

    STL:Standard Template Library,标准模板库