hdu 3987 求最小割条数最小
来源:互联网 发布:pp助手安装不了软件 编辑:程序博客网 时间:2024/06/09 19:27
题意: 一个人要从起点 0 到达 n-1 n个点 m条路 ,我们求最少破坏路的条数使无法 从起点到达终点。题意很明显 ,求最小割条数最少,由于最小割流量虽然固定,但是其条数却不固定,可以破坏3条路,也可以破坏4条路,他们总流量相同才会出现这种情况。
题解:由于上述的情况,他们总流量相同但是条数不同,现在我们需要改变边的容量使得条数少边才是最小割,条数多的将不会是最小割。
官方题解有两种 ,我选择的是在残余网络中进行扩充流的操作,使的两个最小割不同,残余网络中,我进行所有边流量加1的操作,在跑一遍最大流可以得出最小割的最小条数
还有一种方法是在跑最大流之前扩充流量 ,然后对跑出的最小割进行处理得出最小割的最小条数。
代码
#include<stdio.h>
#include<queue>
#include<iostream>
#define INF 0x3f3f3f3f
#define N 1005
using namespace std;
int list[N], listt[N], deep[N], tot;
struct Node
{
int date, next, value;
}cun[2000005];
struct b
{
int x, t;
}old, xin;
void add(int a, int b, int c)
{
cun[++tot].date = b;
cun[tot].value = c;
cun[tot].next = list[a];
list[a] = tot;
cun[++tot].date = a;
cun[tot].value = 0;
cun[tot].next = list[b];
list[b] = tot;
}
int bfs(int s, int t, int n)
{
queue<b> p;
old.x = s;
old.t = 0;
p.push(old);
memset(deep,255,sizeof(deep));
deep[s] = 0;
while(!p.empty())
{
old = p.front();
p.pop();
for(int i = list[old.x]; i; i = cun[i].next)
{
int date = cun[i].date;
int value = cun[i].value;
if(value == 0 || deep[date] != -1) continue;
xin.x = date;
xin.t = old.t + 1;
deep[date] = xin.t;
p.push(xin);
}
}
for(int i = 0; i <= n; i++)
{
listt[i] = list[i];
}
return deep[t] != -1;
}
int minn(int a, int b)
{
if(a < b) return a;
return b;
}
int dfs(int s, int t, int min)
{
if(s == t) return min;
int neww = 0;
for(int i = listt[s]; i; i = cun[i].next)
{
listt[s] = i;
int date = cun[i].date;
int value = cun[i].value;
if(value == 0 || deep[date] != deep[s] + 1) continue;
int m = dfs(date, t, minn(value, min - neww));
neww += m;
cun[i].value -= m;
cun[i^1].value += m;
if(neww == min) break;
}
if(neww == 0) deep[s] = 0;
return neww;
}
int dinic(int s, int t, int n)
{
int num = 0;
while(bfs(s, t, n))
{
num += dfs(s, t, INF);
}
return num;
}
int main()
{
int n, m, a, b, c, flag, T, flagg = 1;
scanf("%d", &T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(list,0,sizeof(list));
tot = 1;
for(int i = 1; i <= m; i++)
{
scanf("%d %d %d %d", &a, &b, &c, &flag);
add(a+1, b+1, c);
if(flag)
add(b+1, a+1, c);
}
int k = dinic(1, n, n+5);
for(int i = 2; i <= tot; i += 2)
{
cun[i].value ++;
}
k = dinic(1, n, n+5);
printf("Case %d: %d\n", flagg++, k);
}
}
- hdu 3987 求最小割条数最小
- 【求最小权值割边】HDU
- hdu 3987(求边最少的最小割)
- HDU--3987[Harry Potter and the Forbidden Forest] 求最小割集中的最小边数
- HDU 3987 求断开两点最小花费下的边数 最小割
- hdu 3987 最小割
- HDU-1233(kruskal求最小生成树)
- HDU-1233(prim求最小生成树)
- HDU-1102(prim求最小生成树)
- hdu 1233 Kruskal求最小生成树
- hdu 2819 求最小顶点覆盖数
- hdu 3746 kmp求最小循环节
- HDU 1599(floyd)(求最小回路问题)
- HDU 3987 最小割模型
- hdu 3987(求割边最小的最小割)
- hdu 1019 求多个数的最小公约数
- HDU-1151(求最小覆盖路径数_二分匹配)
- HDU 3746 Cyclic Nacklace(KMP求最小循环元)
- 《Machine Learning(Tom M. Mitchell)》读书笔记——11、第十章
- getline用法(只读取第一行字幅,待修改)
- 判断圆和矩形是否相交(非面积相交)
- 最小m段和(DP)
- Windows Server AppFabric 简介
- hdu 3987 求最小割条数最小
- codevs1010 过河卒(棋盘dp)
- Low-Rank Matrix Fitting
- 黑马程序员——高新技术1——MyEclipse
- 防盗门如何换锁芯
- Unity3D内存管理——对象池(Object Pool)
- 第十四周项目六 阅读程序(10、11)
- AOP 基础
- 一个应用实例详解卡尔曼滤波及其算法实现