FZU 1844 Earthquake Damage(最大流最小割)
Problem Description
Open Source Tools help earthquake researchers stay a step ahead. Many geological research facilities around the world use or are in the process of developing open source software and applications designed to interpret and share information with other researchers. For example, OpenSees is an open source software framework for developing apps that help understand what happens to structures during and after earthquakes to help engineers design stronger buildings. Researchers are also using OpenSees to understand the potential ill-effects of seismic activity on viaducts and bridges.

China has had an earthquake that has struck Sichuan Province on Monday 12 May 2008!
The earthquake has damaged some of the cities so that they are unpassable. Remarkably, after repairing by Chinese People's Liberation Army, all the driveways between cities were fixed.
As usual, Sichuan Province is modeled as a set of P (1 <= P <= 3,000) cities conveniently numbered 1..P which are connected by a set of C (1 <= C <= 20,000) non-directional driveways conveniently numbered 1..C. Driveway i connects city a_i and b_i (1 <= a_i <= P; 1 <= b_i <= P). Driveway might connect a_i to itself or perhaps might connect two cities more than once. The Crisis Center is located in city 1.
A total of N (1 <= N <= P) survivors (in different cities) sequentially contacts Crisis Center via moobile phone with an integer message report_j (2 <= report_j <= P) that indicates that city report_j is undamaged but that the calling survivor is unable to return to the Crisis Center from city report_j because he/she could not find a path that does not go through damaged city.
After all the survivors report in, determine the minimum number of cities that are damaged.
Input
Input consists of several testcases. The format of each case as follow:
- Line 1: Three space-separated integers: P, C, and N
- Lines 2..C+1: Line i+1 describes cowpath i with two integers: a_i and b_i
- Lines C+2..C+N+1: Line C+1+j contains a single integer: report_j
Output
For each testcase, output a line with one number, the minimum number of damaged cities.
用最大流最小割定理,最大流=最小割,很久以前做的,题目已忘,我是来放模版的
DINIC算法+当前弧优化+有容量上限,78MS
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; #define MAXN 6010
#define MAXM 100010 #define INF 0x7fffffff struct Dinic {
int n, m, st, ed, ecnt;
int vis[MAXN], head[MAXN];
int cur[MAXN], d[MAXN];
int to[MAXM], next[MAXM], flow[MAXM], cap[MAXM]; void init(int ss, int tt){
memset(head,,sizeof(head));
ecnt = ;
st = ss; ed = tt;
} void addEdge(int u,int v,int c) {
//flow[ecnt] = c
to[ecnt] = v; cap[ecnt] = c; flow[ecnt] = ; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; cap[ecnt] = ; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
} bool bfs() {
memset(vis, , sizeof(vis));
queue<int> que; que.push(st);
d[st] = ; vis[st] = true;
while(!que.empty()){
int u = que.front(); que.pop();
for(int p = head[u]; p; p = next[p]){
int v = to[p];
if (!vis[v] && cap[p] > flow[p]){//flow[p] > 0
vis[v] = ;
d[v] = d[u] + ;
que.push(v);
if(v == ed) return true;
}
}
}
return vis[ed];
} int dfs(int u, int a) {
if(u == ed || a == ) return a;
int outflow = , f;
for(int &p = cur[u]; p; p = next[p]){
int v = to[p];
if(d[u] + == d[v] && (f = dfs(v, min(a, cap[p] - flow[p]))) > ){//min(a, flow[p])
flow[p] += f;//flow[p] -= f;
flow[p ^ ] -= f;//flow[p ^ 1] += f;
outflow += f;
a -= f;
if(a == ) break;
}
}
return outflow;
} int Maxflow() {
int ans = ;
while(bfs()){
for(int i = ; i <= ed; ++i) cur[i] = head[i];
ans += dfs(st, INF);
}
return ans;
}
} G; int vis[MAXN]; int main() {
int ss, tt, N, C, P;
while(scanf("%d%d%d",&P,&C,&N)!=EOF){
ss = ; tt = *P+;
G.init(ss, tt);
while(C--){
int a, b;
scanf("%d%d",&a,&b);
G.addEdge(a + P, b, INF);
G.addEdge(b + P, a, INF);
}
memset(vis, , sizeof(vis));
while(N--){
int x;
scanf("%d",&x);
G.addEdge(x, tt, INF);
vis[x] = ;
}
for(int i = ; i <= P; ++i){
if(i != && !vis[i]) G.addEdge(i, i + P, );
else G.addEdge(i, i + P, INF);
}
G.n = tt;
printf("%d\n",G.Maxflow());
}
return ;
}
DINIC算法+当前弧优化+只有余量,62MS
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; #define MAXN 6010
#define MAXM 100010 #define INF 0x7fffffff struct Dinic {
int n, m, st, ed, ecnt;
int vis[MAXN], head[MAXN];
int cur[MAXN], d[MAXN];
int to[MAXM], next[MAXM], flow[MAXM]; void init(int ss, int tt){
memset(head,,sizeof(head));
ecnt = ;
st = ss; ed = tt;
} void addEdge(int u,int v,int f) {
to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
} bool bfs() {
memset(vis, , sizeof(vis));
queue<int> que; que.push(st);
d[st] = ; vis[st] = true;
while(!que.empty()){
int u = que.front(); que.pop();
for(int p = head[u]; p; p = next[p]){
int v = to[p];
if (!vis[v] && flow[p] > ){
vis[v] = ;
d[v] = d[u] + ;
que.push(v);
if(v == ed) return true;
}
}
}
return vis[ed];
} int dfs(int u, int a) {
if(u == ed || a == ) return a;
int outflow = , f;
for(int &p = cur[u]; p; p = next[p]){
int v = to[p];
if(d[u] + == d[v] && (f = dfs(v, min(a, flow[p]))) > ){
flow[p] -= f;
flow[p ^ ] += f;
outflow += f;
a -= f;
if(a == ) break;
}
}
return outflow;
} int Maxflow() {
int ans = ;
while(bfs()){
for(int i = ; i <= ed; ++i) cur[i] = head[i];
ans += dfs(st, INF);
}
return ans;
}
} G; int vis[MAXN]; int main() {
int ss, tt, N, C, P;
while(scanf("%d%d%d",&P,&C,&N)!=EOF){
ss = ; tt = *P+;
G.init(ss, tt);
while(C--){
int a, b;
scanf("%d%d",&a,&b);
G.addEdge(a + P, b, INF);
G.addEdge(b + P, a, INF);
}
memset(vis, , sizeof(vis));
while(N--){
int x;
scanf("%d",&x);
G.addEdge(x, tt, INF);
vis[x] = ;
}
for(int i = ; i <= P; ++i){
if(i != && !vis[i]) G.addEdge(i, i + P, );
else G.addEdge(i, i + P, INF);
}
G.n = tt;
printf("%d\n",G.Maxflow());
}
return ;
}
ISAP算法,78MS(把注释删掉再交一次又变成了93MS,OJ的时间果然信不过o(╯□╰)o)//不能有点0
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; #define MAXN 6010
#define MAXM 100010
#define INF 0x7fffffff struct SAP {
int vis[MAXN], head[MAXN];
int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN];
int to[MAXM], flow[MAXM], next[MAXM];
int ecnt, st, ed; void init(int ss, int tt) {
memset(head, , sizeof(head));
ecnt = ;
st = ss; ed = tt;
} void addEdge(int u,int v,int f) {
to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
} int Max_flow() {
int ans = , minFlow = INF, n = ed, u;
for (int i = ; i <= n; ++i){
cur[i] = head[i];
gap[i] = dis[i] = ;
}
u = pre[st] = st;
gap[] = n;
while (dis[st] < n){
bool flag = false;
for (int &p = cur[u]; p; p = next[p]){
int v = to[p];
if (flow[p] > && dis[u] == dis[v] + ){
flag = true;
minFlow = min(minFlow, flow[p]);
pre[v] = u;
u = v;
if(u == ed){
ans += minFlow;
while (u != st){
u = pre[u];
flow[cur[u]] -= minFlow;
flow[cur[u] ^ ] += minFlow;
}
minFlow = INF;
}
break;
}
}
if (flag) continue;
int minDis = n-;
for (int p = head[u]; p; p = next[p]){
int v = to[p];
if (flow[p] && dis[v] < minDis){
minDis = dis[v];
cur[u] = p;
}
}
if (--gap[dis[u]] == ) break;
gap[dis[u] = minDis+]++;
u = pre[u];
}
return ans;
}
} G; bool vis[MAXN]; int main() {
int ss, tt, N, C, P;
while(scanf("%d%d%d",&P,&C,&N)!=EOF) {
ss = ; tt = *P+;
G.init(ss, tt);
while(C--) {
int a, b;
scanf("%d%d",&a,&b);
G.addEdge(a + P, b, INF);
G.addEdge(b + P, a, INF);
}
memset(vis, , sizeof(vis));
while(N--) {
int x;
scanf("%d",&x);
G.addEdge(x, tt, INF);
vis[x] = ;
}
for(int i = ; i <= P; ++i) {
if(i != && !vis[i]) G.addEdge(i, i + P, );
else G.addEdge(i, i + P, INF);
}
printf("%d\n",G.Max_flow());
}
return ;
}
ISAP算法+BFS初始化,62MS(SGU 438把我这模板跑跪了,现在换掉了>_<)//不能有点0
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; #define MAXN 6010
#define MAXM 100010
#define INF 0x7fffffff struct SAP {
int head[MAXN];
int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN];
int to[MAXM], flow[MAXM], next[MAXM];
int ecnt, st, ed, n; void init(int ss, int tt, int nn) {
memset(head, , sizeof(head));
ecnt = ;
st = ss; ed = tt; n = nn;
} void addEdge(int u,int v,int f) {
to[ecnt] = v; flow[ecnt] = f; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
} void bfs() {
memset(dis, 0x3f, sizeof(dis));
queue<int> que; que.push(ed);
dis[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
++gap[dis[u]];
for(int p = head[u]; p; p = next[p]) {
int v = to[p];
if (dis[v] > ed && flow[p ^ ] > ) {
dis[v] = dis[u] + ;
que.push(v);
}
}
}
} int Max_flow() {
int ans = , minFlow = INF, u;
for (int i = ; i <= n; ++i){
cur[i] = head[i];
gap[i] = dis[i] = ;
}
u = pre[st] = st;
//gap[0] = n;
bfs();
while (dis[st] < n){
bool flag = false;
for (int &p = cur[u]; p; p = next[p]){
int v = to[p];
if (flow[p] > && dis[u] == dis[v] + ){
flag = true;
minFlow = min(minFlow, flow[p]);
pre[v] = u;
u = v;
if(u == ed){
ans += minFlow;
while (u != st){
u = pre[u];
flow[cur[u]] -= minFlow;
flow[cur[u] ^ ] += minFlow;
}
minFlow = INF;
}
break;
}
}
if (flag) continue;
int minDis = n-;
for (int p = head[u]; p; p = next[p]){
int v = to[p];
if (flow[p] && dis[v] < minDis){
minDis = dis[v];
cur[u] = p;
}
}
if (--gap[dis[u]] == ) break;
gap[dis[u] = minDis+]++;
u = pre[u];
}
return ans;
}
} G; bool vis[MAXN]; int main() {
int ss, tt, N, C, P;
while(scanf("%d%d%d",&P,&C,&N)!=EOF) {
ss = ; tt = *P+;
G.init(ss, tt, tt);
while(C--) {
int a, b;
scanf("%d%d",&a,&b);
G.addEdge(a + P, b, INF);
G.addEdge(b + P, a, INF);
}
memset(vis, , sizeof(vis));
while(N--) {
int x;
scanf("%d",&x);
G.addEdge(x, tt, INF);
vis[x] = ;
}
for(int i = ; i <= P; ++i) {
if(i != && !vis[i]) G.addEdge(i, i + P, );
else G.addEdge(i, i + P, INF);
}
printf("%d\n",G.Max_flow());
}
return ;
}
FZU 1844 Earthquake Damage(最大流最小割)的更多相关文章
- bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害
1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 Description Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着 ...
- hiho 第116周,最大流最小割定理,求最小割集S,T
小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...
- hihocoder 网络流二·最大流最小割定理
网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...
- [HihoCoder1378]网络流二·最大流最小割定理
思路: 根据最大流最小割定理可得最大流与最小割相等,所以可以先跑一遍EdmondsKarp算法.接下来要求的是经过最小割切割后的图中$S$所属的点集.本来的思路是用并查集处理所有前向边构成的残量网络, ...
- HDU 1569 方格取数(2)(最大流最小割の最大权独立集)
Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. ...
- 【codevs1907】方格取数3(最大流最小割定理)
网址:http://codevs.cn/problem/1907/ 题意:在一个矩阵里选不相邻的若干个数,使这些数的和最大. 我们可以把它看成一个最小割,答案就是矩阵中的所有数-最小割.先把矩阵按国际 ...
- 洛谷 P2932 [USACO09JAN]地震造成的破坏Earthquake Damage
P2932 [USACO09JAN]地震造成的破坏Earthquake Damage 题目描述 Wisconsin has had an earthquake that has struck Farm ...
- 紫书 例题 11-12 UVa 1515 (最大流最小割)
这道题要分隔草和洞, 然后刘汝佳就想到了"割"(不知道他怎么想的, 反正我没想到) 然后就按照这个思路走, 网络流建模然后求最大流最小割. 分成两部分, S和草连, 洞和T连 外围 ...
- HDU-4289-Control(最大流最小割,拆点)
链接: https://vjudge.net/problem/HDU-4289 题意: You, the head of Department of Security, recently receiv ...
随机推荐
- php 计算两个文件的相对路径
<?php /** * 计算两个文件的相对路径 */ function relative_path($path1, $path2) { $arr1 = explode('/', dirname( ...
- linux操作之ntsysv
命令nysysv , 提示Command nod found 先在命令行输入 export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin: ...
- python 爬虫(爬取网页的img并下载)
from urllib.request import urlopen # 引用第三方库 import requests #引用requests/用于访问网站(没安装需要安装) from pyquery ...
- BugkuWeb本地包含
知识点:$_REQUEST不是一个函数,它是一个超全局变量,里面包括有$_GET $_POST $_COOKIE的值,$_REPUEST 是接收了 $_GET $_POST $_COOKIE 三个的集 ...
- C语言中字符串赋值的几个理解
在C语言中,字符串的赋值主要有两种方法,第一种是通过指针的方式直接赋值,第二种是通过数组直接赋值. 一.首先,我们来看第一种赋值方法:指针式赋值 我们知道,上面的示例是显然可以正常执行的,也是很容易理 ...
- Codeforces Round #490 (Div. 3) :F. Cards and Joy(组合背包)
题目连接:http://codeforces.com/contest/999/problem/F 解题心得: 题意说的很复杂,就是n个人玩游戏,每个人可以得到k张卡片,每个卡片上有一个数字,每个人有一 ...
- SpaceVim 语言模块 elm
原文连接: https://spacevim.org/cn/layers/lang/elm/ 模块简介 功能特性 依赖安装及启用模块 依赖安装 启用模块 快捷键 语言专属快捷键 交互式编程 模块简介 ...
- HDL代码风格建议(1)使用示例和IP
Recommended HDL Coding Styles HDL coding styles can have a significant effect on the quality of resu ...
- 20145209 2016-2017-2 《Java程序设计》第2周学习总结
20145209 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 git log 命令来查看 :提交历史 查看当前所处位置: pwd git 版本控制 tou ...
- Python之celery
一.celery简介 Celery是一个Python开发的异步分布式任务调度模块.celery本身不提供消息服务,使用第三方服务,也就是borker来传递任务,目前支持rebbing, redis, ...