hdu3987,最小割时求最少割边数
题意:求最小割时候割边最少的数量。算法:先求dinic一遍,跑出残网络,再把该网络中满流量(残量为0)的边
残量改为1,其他边残量改为无穷,则再跑一次最大流,所得即为答案。(思,最小割有喝多组,但是要割边数量最少
的,那么把满流的流量改为1,再跑一次最大流即可)。
未1A原因:
1*:添加边的时候,把双向边添加为一条(反向的流量上限==正向),这样不是不可以,但是由于后面用到要取有效边
(非后悔边,边编号比为偶数),导致错误,改为添加俩次即可。
2//:数据较大,总流量10W*1000,可能暴int。
#include<iostream> //98ms
#include<cstdio>
#include<queue>
using namespace std;
long long e[400001][3];int head[1100];const int inf=0x3f3f3f3f;
int n,m;int nume;
void addedge(int from,int to,int w,int derect) //添加边的函数,derect为1时要添加双向边
{
e[nume][0]=to; e[nume][1]=head[from];head[from]=nume;
e[nume++][2]=w;
e[nume][0]=from; e[nume][1]=head[to];head[to]=nume;
e[nume++][2]=0;
if(derect==1)
{
e[nume][0]=from; e[nume][1]=head[to];head[to]=nume;
e[nume++][2]=w;
e[nume][0]=to; e[nume][1]=head[from];head[from]=nume;
e[nume++][2]=0;
}
}
int level[1100];int vis[1100];
bool bfs() //dinic
{
for(int i=0;i<=n;i++)
vis[i]=level[i]=0;
queue<int>q;q.push(0);
vis[0]=1;
while(!q.empty())
{
int cur=q.front();q.pop();
for(int i=head[cur];i!=-1;i=e[i][1])
{ int v=e[i][0];
if(!vis[v]&&e[i][2]>0)
{
level[v]=level[cur]+1;
if(v==n-1)return 1;
vis[v]=1;
q.push(v);
}
}
}
return vis[n-1];
}
long long dfs(int u,long long minf)
{
if(u==n-1||minf==0)return minf;
long long sumf=0,f;
for(int i=head[u];i!=-1&&minf;i=e[i][1])
{ int v=e[i][0];
if(level[v]==level[u]+1&&e[i][2]>0)
{
f=dfs(v,minf<e[i][2]?minf:e[i][2]);
e[i][2]-=f;e[i^1][2]+=f;
minf-=f;sumf+=f;
}
}
return sumf;
}
long long dinic()
{
long long sum=0;
while(bfs())
{
sum+=dfs(0,inf);
}
return sum;
}
long long getmincut()
{
long long cutedge=0;
for(int i=0;i<=n;i++)
vis[i]=0;
queue<int>q;q.push(0);vis[0]=1;
while(!q.empty())
{
int cur=q.front();q.pop();
for(int i=head[cur];i!=-1;i=e[i][1])
{ int v=e[i][0];
if(i%2==0&&e[i][2]==0) //边数偶数的边是残量网络有效边(非后悔边)
{ e[i][2]=1;e[i^1][2]=0;}
else if(i%2==0&&e[i][2]>0)
{e[i][2]=inf;e[i^1][2]=0;}
if(!vis[v]&&e[i][2]>=0)
{
vis[v]=1;q.push(v);
}
}
}
cutedge=dinic();
return cutedge;
}
int main()
{
int N;scanf("%d",&N); int casenum=1;
while(N--)
{
scanf("%d%d",&n,&m);
nume=0;
for(int i=0;i<=n;i++)
head[i]=-1;
for(int i=0;i<m;i++)
{ int from,to,w,d;
scanf("%d%d%d%d",&from,&to,&w,&d);
addedge(from,to,w,d);
}
dinic();
long long ans=getmincut();
printf("Case %d: %lld\n",casenum,ans);
casenum++;
}
return 0;
}
hdu3987,最小割时求最少割边数的更多相关文章
- BZOJ_1001_狼抓兔子_(平面图求最小割+对偶图求最短路)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec ...
- [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割
题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...
- 网络流+最小生成树的最少割边数--How Many to Be Happy?
题意:https://blog.csdn.net/Ratina/article/details/95200594 思路: 首先我们知道最小生成树就是按长度枚举边,能连就连. 那么,如果这条边在最小生成 ...
- HDU 3987 Harry Potter and the Forbidden Forest(边权放大法+最小割)
Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65536/ ...
- hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割
view code//hdu 3987 #include <iostream> #include <cstdio> #include <algorithm> #in ...
- HDU 6214.Smallest Minimum Cut 最少边数最小割
Smallest Minimum Cut Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Oth ...
- TZOJ 5110 Pollutant Control(边数最少最小割最小字典序输出)
描述 It's your first day in Quality Control at Merry Milk Makers, and already there's been a catastrop ...
- hdu 6214 Smallest Minimum Cut(最小割的最少边数)
题目大意是给一张网络,网络可能存在不同边集的最小割,求出拥有最少边集的最小割,最少的边是多少条? 思路:题目很好理解,就是找一个边集最少的最小割,一个方法是在建图的时候把边的容量处理成C *(E+1 ...
- HDU 3657 Game(取数 最小割)经典
Game Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
随机推荐
- k sum(lintcode)
没通过的代码: class Solution { public: /* * @param A: An integer array * @param k: A positive integer (k & ...
- CPP-基础:C++拷贝构造函数详解
一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: ; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象 ...
- Codeforces Round #277.5 (Div. 2)-C. Given Length and Sum of Digits...
http://codeforces.com/problemset/problem/489/C C. Given Length and Sum of Digits... time limit per t ...
- java socket domain name 使用域名.
java 的 socket 依赖了 nameService. 引擎模式. 使得 socket tcp 层 具有了上层业务的能力 (应用层) Socket socket=new Socket(&quo ...
- shell脚本,计算1+2+3+....100等于多少?
第一种方法,通过for循环来计算[root@localhost wyb]# cat yibai.sh #!/bin/bash #从1+++...100的结果 i= ` do sum=$(($sum+i ...
- vue 点击倒计时 ajax 封装
方法:function(){ var that = this; if (that.time == 0) { that.disabled = false; that.text ="点击获取&q ...
- java面试宝典第二弹
arraylist和linklist的区别,hashmap和hashset的区别,常用的集合有哪些 一.基础内容 容器就是一种装其他各种对象的器皿.java.util包 容器:Set, List, M ...
- Bzoj 1055: [HAOI2008]玩具取名 (区间DP)
Bzoj 1055: [HAOI2008]玩具取名 (区间DP) 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1055 区间动态规划和可 ...
- hihoCoder-1097-Prim
这题就是prim的板子题,不过如果用end每次初始化为-1的话,我们就不需要对于每次选中的下一个点进行判断是否选中了,因为每次外层循环第一次进入都是可以的. 然后还很 (i=1:i<=n;i++ ...
- 【搜索 技巧】Letter gaps
需要一定技巧的搜索题 题目描述 记得做过这样一道题 Ponder This Challenge: In the string CABACB, each letter appears exactly t ...