地震破坏

时间限制: 1 Sec  内存限制: 128 MB

题目描述

威斯康星发生了一场地震!约翰的牧场遭到了打击,有一些牛棚变成了废墟,如果一间牛棚遭到
了破坏,那么所有和它相连的道路都不能使用了。
约翰有 N 个牛棚,编号为 1 到 N,有 M 条双向道路连接这些牛棚,第 i 条道路连接的牛棚是
A i 和 B i ,A i 可能等于 B i ,也可能有多条道路连接同一对牛棚。
约翰让奶牛们集中到 1 号牛棚避难。有 P 头奶牛通过手机向约翰求救,她们的遭遇类似:好消
息是她们所在的牛棚没有损坏,坏消息是由于其他的牛棚遭到破坏,所以她们找不到任何可以走到 1
号牛棚的路径。假设发送报告的第 i 头奶牛目前在牛棚 R i 里,那么以最乐观的情况来看,至少有多
少牛棚被破坏了呢?

输入

• 第一行:三个整数 N,M 和 P, 1 ≤ P ≤ N ≤ 3000, 1 ≤ M ≤ 20000
• 第二行到第 M + 1 行:第 i + 1 行有两个整数 A i 和 B i ,1 ≤ A i ,B i ≤ N
• 第 M + 2 行到第 M + P + 1 行:第 i + M + 1 行有一个整数 R i , 1 ≤ R i ≤ N,保证每个 R i 都
是不同的

输出

• 单个整数:表示至少有几个牛棚被破坏了

样例输入

5 5 2
1 2
2 3
3 5
2 4
4 5
4
5

样例输出

1

提示

最乐观的情况是只有 2 号牛棚坏了

题解:

一道比较经典的最小割,首先因为每次删除的是一个点,所以要将每个点拆开,将1节点和打电话过来的几个节点残量设为最大值,其余的为1。(为了让割边落在可以去掉的点上)这样就可以将去点转化为割边。

然后根据图的连接方式,若节点x被分为x1和x2,节点y被分为y1和y2。若x和y连接,则将x2连y1,y2连x1,残量都为最大值。

然后跑一遍网络流就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#define inf (2e8)
using namespace std;
int n,m,l;
struct node
{
int next,to,cap;
}edge[];
int head[],size=,a[];
void putin(int from,int to,int cap)
{
size++;
edge[size].next=head[from];
edge[size].to=to;
edge[size].cap=cap;
head[from]=size;
}
void in(int from,int to,int cap)
{
putin(from,to,cap);
putin(to,from,);
}
int dist[],numbs[];
void bfs(int src,int des)
{
int i;
queue<int>mem;
mem.push(des);
dist[des]=;numbs[]++;
while(!mem.empty())
{
int x=mem.front();mem.pop();
for(i=head[x];i!=-;i=edge[i].next)
{
int y=edge[i].to;
if(edge[i].cap==&&dist[y]==&&y!=des)
{
dist[y]=dist[x]+;
numbs[dist[y]]++;
mem.push(y);
}
}
}
return;
}
int dfs(int src,int flow,int des)
{
if(src==des)return flow;
int i,low=,mindist=n*+;
for(i=head[src];i!=-;i=edge[i].next)
{
int y=edge[i].to;
if(edge[i].cap)
{
if(dist[y]==dist[src]-)
{
int t=dfs(y,min(flow-low,edge[i].cap),des);
edge[i].cap-=t;
edge[i^].cap+=t;
low+=t;
if(dist[src]>=n*+)return low;
if(low==flow)break;
}
mindist=min(mindist,dist[y]+);
}
}
if(!low)
{
if(!(--numbs[dist[src]]))dist[]=n*+;
++numbs[dist[src]=mindist];
}
return low;
}
int ISAP(int src,int des)
{
int ans=;
bfs(src,des);
while(dist[]<n*+)ans+=dfs(src,2e8,des);
return ans;
}
int main()
{
int i,j;
memset(head,-,sizeof(head));
scanf("%d%d%d",&n,&m,&l);
for(i=;i<=m;i++)
{
int from,to;
scanf("%d%d",&from,&to);
in(n+from,to,inf);
in(n+to,from,inf);
}
for(i=;i<=l;i++){scanf("%d",&j);a[j]=;}
in(,n+,inf);
for(i=;i<=n;i++)
{
if(a[i]==){in(i,n+i,inf);in(n+i,*n+,inf);}
else in(i,n+i,);
}
in(,,inf);
int maxflow=ISAP(,n*+);
cout<<maxflow;
return ;
}

[USACO09MAR]地震损失2Earthquake Damage 2的更多相关文章

  1. P2944 [USACO09MAR]地震损失2Earthquake Damage 2(网络流)

    P2944 [USACO09MAR]地震损失2Earthquake Damage 2 $P$个点,$C$条双向边.求最少删去几个点使$N$个给定的点与点$1$分开. 显然的最小割. 将点$i$套路地拆 ...

  2. 洛谷2944 [USACO09MAR]地震损失2Earthquake Damage 2

    https://www.luogu.org/problem/show?pid=2944 题目描述 Wisconsin has had an earthquake that has struck Far ...

  3. p2944 [USACO09MAR]地震损失2Earthquake Damage 2

    传送门 分析 我们让s到1,关键点到t分别连流量为inf的边 于是我们可以考虑跑s到t的最小割 于是我们将所有点拆为两个点,关键点和1的两个点之间连inf,其余点连1 将原图的边也连上,流量为inf ...

  4. 【BZOJ1585】【Luogu2944】地震损失2(网络流)

    [BZOJ1585][Luogu2944]地震损失2(网络流) 题面 题目描述 Wisconsin has had an earthquake that has struck Farmer John' ...

  5. 【P2944】地震损失(最大流,洛谷)

    绝对难度虚高的一题 看到题目,至少损坏几个房子,开始考虑最小割,建的是双向边,所以拆点,边权除了自己与自己的之外都连inf.然后把所有求救的点都连到超级源上,跑一遍最大流就可以了. #include& ...

  6. 1574: [Usaco2009 Jan]地震损坏Damage

    1574: [Usaco2009 Jan]地震损坏Damage Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 425  Solved: 232[Subm ...

  7. bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害

    1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 Description Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着 ...

  8. 洛谷 P2932 [USACO09JAN]地震造成的破坏Earthquake Damage

    P2932 [USACO09JAN]地震造成的破坏Earthquake Damage 题目描述 Wisconsin has had an earthquake that has struck Farm ...

  9. BZOJ 1574: [Usaco2009 Jan]地震损坏Damage

    Description 农夫John的农场遭受了一场地震.有一些牛棚遭到了损坏,但幸运地,所有牛棚间的路经都还能使用. FJ的农场有P(1 <= P <= 30,000)个牛棚,编号1.. ...

随机推荐

  1. 每个国家对应的语言Locale和国家代码对照表

    DNN3支持多语言,希望下面的语言代码与对应国家能对你有所帮助 语言代码 国家/ 地区 "" (空字符串) 无变化的文化 af 公用荷兰语 af-ZA 公用荷兰语 - 南非 sq ...

  2. 转载+++++iptables详解+++++转载

    转载:http://blog.chinaunix.net/uid-26495963-id-3279216.html 一.前言 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件 ...

  3. Linux上rpm方式安装JDK1.7

    说明: 1.Linux版本 CentOS6.5_x86 2.Java版本 JDK1.7 32位的rpm包,所以是以rpm方式安装的java 3.可以使用yum install java从yum源中安装 ...

  4. Java学习笔记——排序算法之进阶排序(堆排序与分治并归排序)

    春蚕到死丝方尽,蜡炬成灰泪始干 --无题 这里介绍两个比较难的算法: 1.堆排序 2.分治并归排序 先说堆. 这里请大家先自行了解完全二叉树的数据结构. 堆是完全二叉树.大顶堆是在堆中,任意双亲值都大 ...

  5. 【安装Python环境】之“安装 setuptools ”时出现的问题以及解决办法

    安装Python环境时,还需要安装"setuptools 与 pip",但是安装setuptools时出现了几个问题,如下: setuptools 与 pip 下载地址如下:htt ...

  6. python 冒泡排序,递归

    冒泡排序:li = [33, 55, 58, 66, 58, 555,20000000000000000000000, 5555,5555, 5, 6, 62,1]for i in range(1,l ...

  7. OpenCV探索之路(八):重映射与仿射变换

    重映射 重映射就是把一幅图像中某个位置的像素放置到另一个图片中指定位置的过程. 用一个数学公式来表示就是: 其中的 f 就是映射方式,也就说,像素点在另一个图像中的位置是由 f 来计算的. 在Open ...

  8. 关于MySQL数据库的一些操作

    启动:net start MySQL 关闭:net stop MySQL (也可以用quit:) 登录到MySQL:mysql -u root -p -u : 所要登录的用户名; -p : 告诉服务器 ...

  9. javascript 面向对象基础 (1)

    常见的创建对象的方式有3种: ① 声明变量的方式 var obj1 = { key1: "val1", key1: "val2", show: function ...

  10. CefSharp使用入门

    首先这是很重要的,环境搭建: 我用的是VS2017 步骤            方法 1.            打开VS的安装管理器 2.             进入修改界面,使用C++的桌面开发 ...