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 ...
随机推荐
- asp.net 实现对xml文件的 读取,添加,删除,修改
用于修改站内xml文件 已知有一个XML文件(bookstore.xml)如下:<?xml version="1.0" encoding="gb2312" ...
- Node中Exports与module.export的使用与区别
最近在看<node开发实战详解>时有写疑问,所以自己就整理了一些资料.下面是node4.*的官方api文档(http://nodejs.cn/doc/node_4/modules.html ...
- Hessian(C#)介绍及使用说明
什么是Hessian? Hessian是Caucho开发的一种二进制Web Service协议.支持目前所有流行的开发平台. Hessia能干什么? hessian用来实现web服务. Hessia有 ...
- sp_addlinkedserver的一些操作
sp_addlinkedserver 创建一个链接的服务器,使其允许对分布式的.针对 OLE DB 数据源的异类查询进行访问.在使用 sp_addlinkedserver 创建链接的服务器之后,此服务 ...
- IOS 中得runloop 详细解释
1.Runloop基础知识- 1.1 字面意思 a 运行循环 b 跑圈 - 1.2 基本作用(作用重大) a 保持程序的持续运行(ios程序为什么能一直活着不会死) b 处理app中的各种事件(比如触 ...
- basicAnimation移动图形
目的:采用CABasicAnimation 点击屏幕上的点来是实现图像的位置移动 并且位置能够不反弹 难点:1 通过动画的KeyPath找到layer的属性 2 通过NSValue将点包装成对象 ...
- C# 封装
封装就是吧里面实现的细节包起来,这样很复杂的逻辑经过包装之后给别人使用就很方便,别人不需要了解里面是如何实现的,只要传入所需要的参数就可以得到想要的结果.其实这和黑盒测试差不多
- [转]mysql 导入导出数据库以及函数、存储过程的介绍
本篇文章是对mysql中的导入导出数据库命令以及函数.存储过程进行了详细的分析介绍,需要的朋友参考下: mysql常用导出数据命令:1.mysql导出整个数据库 mysqldump -hhostna ...
- PowerDesigner 的7种建模文件
1. 概念数据模型 (CDM) 对数据和信息进行建模,利用实体-关系图(E-R图)的形式组织数据,检验数据设计的有效性和合理性. 2. 逻辑数据模型 (LDM) PowerDesigner 15 ...
- 由Python的super()函数想到的
python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...