poj 3084 最小割
题目链接: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 最小割的更多相关文章
- poj 2125(最小割)
题目链接:http://poj.org/problem?id=2125 思路:将最小点权覆盖转化为最小割模型,于是拆点建图,将点i拆成i,i+n,其中vs与i相连,边容量为w[i]-,i+n与vt相连 ...
- poj 3204(最小割--关键割边)
Ikki's Story I - Road Reconstruction Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 7 ...
- POJ 3469 最小割 Dual Core CPU
题意: 一个双核CPU上运行N个模块,每个模块在两个核上运行的费用分别为Ai和Bi. 同时,有M对模块需要进行数据交换,如果这两个模块不在同一个核上运行需要额外花费. 求运行N个模块的最小费用. 分析 ...
- 网络流 poj 3308 最小割
t个样例 n*m的矩阵 L个伞兵 给出每行每列装激光的花费 伞兵的位置 要求杀死所有伞兵 总费用为这些费用的乘积 求花费最小 建图 源点 -> 行 -> 列 -> 汇点 ...
- poj 3469 最小割模板sap+gap+弧优化
/*以核心1为源点,以核心2为汇点建图,跑一遍最大流*/ #include<stdio.h> #include<string.h> #include<queue> ...
- poj 3084(最小割)
题目链接:http://poj.org/problem?id=3084 思路:题目的意思是不让入侵者进入保护的房间,至少需要锁几道门.网络流建模:设一个超级源点,源点与有入侵者的房间相连,边容量为in ...
- POJ 3084 Panic Room (最小割建模)
[题意]理解了半天--大意就是,有一些房间,初始时某些房间之间有一些门,并且这些门是打开的,也就是可以来回走动的,但是这些门是确切属于某个房间的,也就是说如果要锁门,则只有在那个房间里才能锁. 现在一 ...
- 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 ...
- poj 1815 Friendship 字典序最小+最小割
题目链接:http://poj.org/problem?id=1815 In modern society, each person has his own friends. Since all th ...
随机推荐
- 美好头标ToolBar
ActionBar我相信是每一位合格的程序员都用过的组件,也是每一个程序员都会抱怨的组件,因为他不能实现复杂的自定义.为此Google推出了比ActionBar更为美好的组件ToolBar. 本文重点 ...
- JavaScript Array(数组) 对象
更多实例 合并两个数组 - concat() 合并三个数组 - concat() 用数组的元素组成字符串 - join() 删除数组的最后一个元素 - pop() 数组的末尾添加新的元素 - push ...
- JavaScript HTML DOM EventListener
JavaScript HTML DOM EventListener addEventListener() 方法 实例 点用户点击按钮时触发监听事件: document.getElementById(& ...
- 使用IDEA,利用SpringMVC框架建立HelloWorld项目
无论是从头开始学习一门新的语言还是技术,我们的入门都是从HelloWorld开始,也许就是因为这样,我在学习Spring MVC的时候,就有一种偏执,一定要写出一个HelloWorld来.研究了好久, ...
- 226. Invert Binary Tree(C++)
226. Invert Binary Tree Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 ...
- Vijos1825 NOI2008 志愿者招募 费用流
Orz ByVoid大神的题解:https://www.byvoid.com/blog/noi-2008-employee/ 学习网络流建图的好题,不难想到线性规划的模型,不过利用模型的特殊性,结合网 ...
- 头一回发博客,来分享个有关C++类型萃取的编写技巧
废话不多说,上来贴代码最实在,哈哈! 以下代码量有点多,不过这都是在下一手一手敲出来的,小巧好用,把以下代码复制出来,放到相应的hpp文件即可,VS,GCC下均能编译通过 #include<io ...
- Ubuntu14.04+CUDA6.5环境下神经网络工具包Deepnet配置
deepnet是多伦多大学计算机系机器学习组开发的一个神经网络工具包,可以进行以下计算: 1. Feed-forward Neural Nets 2. Restricted Boltzmann M ...
- C语言-01基础语法
1) 总结常见文件的拓展名 .c 是C语言源文件,在编写代码的时候创建 .o 是目标文件,在编译成功的时候产生 .out 是可执行文件,在链接成功的时候产生 2) 总结 ...
- JSP HTML区别
1.最简单的区别就是,HTML能直接打开,jsp只能发布到Tomact等服务器上才能打开2.定义上HTML页面是静态页面可以直接运行,JSP页面是动态页它运行时需要转换成servlet.3.他们的表头 ...