最大流最小割一题

a

看完题目,根本没想法,暴力的复杂度是指数级别的,枚举所有的集合,当时有点紧张,暴力的都没写,其实没思路的

时候最好写暴力的算法,骗点分就可以了。后来,看了牛客网上大神的思路,然后学习了下最大流最小割的方法,这题的

做法就是枚举源点和汇点,跑最大流算法,然后用流量更新答案,同时保存最小割,最后输出,就可以了。

简单写了下,也是无法实际运行去判断正误。

对最大流最小割的思路理解的不是很透彻,不知道怎么求最小割,没有做这方面的练习。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 #include <cmath>
  6 #include <algorithm>
  7 using namespace std;
  8
  9 const int mn=422;
 10 const int mm=10000;
 11 const double oo=999999;
 12 int node, st, sd, edge;
 13 int reach[mm], nxt[mm];
 14 double flow[mm];
 15 int adj[mn], work[mn], dis[mn], que[mn], cap[mn];
 16
 17 inline void init(int _node, int _st, int _sd)
 18 {
 19     node=_node, st=_st, sd=_sd;
 20     for(int i=0; i<node; i++)
 21         adj[i]=-1;
 22     edge=0;
 23 }
 24
 25 inline void addedge(int u, int v, double c1, double c2)
 26 {
 27     reach[edge]=v, flow[edge]=c1, nxt[edge]=adj[u], cap[edge] = c1, adj[u]=edge++;
 28     reach[edge]=u, flow[edge]=c2, nxt[edge]=adj[v], cap[edge] = c2, adj[v]=edge++;
 29 }
 30
 31 bool bfs()
 32 {
 33     int i,u,v,l,r=0;
 34     for(i=0; i<node; ++i)dis[i]=-1;
 35     dis[que[r++]=st]=0;
 36     for(l=0; l<r; ++l)
 37         for(i=adj[u=que[l]]; i>=0; i=nxt[i])
 38             if(flow[i]&&dis[v=reach[i]]<0)
 39             {
 40                 dis[que[r++]=v]=dis[u]+1;
 41                 if(v==sd)return 1;
 42             }
 43     return 0;
 44 }
 45 typedef pair<int, int> pii;
 46 vector<pii> getCut() {
 47     int l, r = 0, u, v;
 48     que[r++] = st;
 49     vector<pii> res;
 50     vector<bool> in(node, 0);
 51     for (l = 0; l < r; l++) {
 52         if(in[que[l] ]) continue;
 53         in[que[l] ] = 1;
 54         for (int i = adj[u = que[l]]; i >= 0; i = nxt[i]) {
 55             //cout << reach[i] <<" ";
 56             if(flow[i] != 0) {
 57                 que[r++] = reach[i];
 58             } else {
 59                 int x = u, y = reach[i];
 60                 if(x > y) swap(x, y);
 61                 res.push_back({x, y});
 62             }
 63         }
 64         //cout << endl;
 65     }
 66     return res;
 67 }
 68
 69 double dfs(int u,double exp)
 70 {
 71     if(u==sd) return exp;
 72     double  tmp;
 73     for(int &i=work[u],v; i>=0; i=nxt[i])
 74         if(flow[i]&&dis[v=reach[i]]==dis[u]+1&&(tmp=dfs(v,min(exp,flow[i])))>0)
 75         {
 76             flow[i]-=tmp;
 77             flow[i^1]+=tmp;
 78             return tmp;
 79         }
 80     return 0;
 81 }
 82
 83 double Dinic()
 84 {
 85     double max_flow=0, flow;
 86     while(bfs())
 87     {   //cout << "asd" << endl;
 88         for(int i=0; i<node; i++)   work[i]=adj[i];
 89         while(flow=dfs(st,oo)) {
 90             //cout << flow << endl;
 91             max_flow+=flow;
 92         }
 93     }
 94     return max_flow;
 95 }
 96 //上面从网上搜索的,注意修改顶点数,边数,这里边数是2倍,注意节点的编号,从0开始。
 97 //当然,你必须知道dinic算法的逻辑才行。
 98 struct Node {
 99     int x, y, v;
100 };
101 int main()
102 {
103     freopen("test.in", "r", stdin);
104     int  n, m;
105     scanf("%d%d",&n,&m);
106     int x, y, v;
107     vector<Node> e;
108     for (int i = 0; i < m; i++) {
109         scanf("%d%d%d", &x, &y, &v);
110         e.push_back({x, y, v});
111     }
112     int res = INT_MAX;
113     vector<pii> p;
114     for (int i = 1; i <= n; i++) {
115         for (int j = i + 1; j <= n; j++) {
116             init(n + 1, i, j);
117             for (Node t : e) {
118                 addedge(t.x, t.y, t.v, t.v);
119             }
120             double ans=Dinic();
121             if(ans < res) {
122                 res = ans;
123                 p = getCut();
124             }
125         }
126     }
127     //cout << res << endl;
128     sort(p.begin(), p.end());
129     for (pii t : p)
130         cout << t.first << " " << t.second << endl;
131     return 0;
132 }

时间: 2024-11-03 22:51:49

最大流最小割一题的相关文章

HDU-4289-Control(最大流最小割,拆点)

链接: https://vjudge.net/problem/HDU-4289 题意: You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination)

hihocoder 网络流二&#183;最大流最小割定理

网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c(u,v).网络流的最大流问题求解的就是从s到t最多能有多少流量. 小Hi:那这个问题解决办法呢? 小Ho:解决网络流的基本思路就是寻找增广路,不断更新残留网络.直到找不到新的增广路,此时得到的

网络的最大流最小割定理

什么是流(flow): 在一个有向图中,只有出去的边没有进来的边的节点叫做源(source),只有进来的边没有出去的边的节点叫做汇(sink),其它的节点进来的边和出去的边应该是平衡的. 边上可以加权值,假设对于一个交通图来说,可以认为边上的权重为一条道路上的最大流量.那么对于图中任意两个节点来说,它们之间可以存在很多路径,每条路径上可以负载的最大流量应该是这条路径上权重最小的那条边所能承载的流量(联想一下“瓶颈”这个词,或者木桶理论),那么所有的路径上所负载流量之和也就是这两个节点之间多能通过

最大流最小割C++实现

最大流量问题:寻找从源点到汇点的最大流量. 使用最短增益路径法(或先标记先扫描法).这里标记意味着用两个记号来标记一个新的(为标记)的顶点:第一个标记指出从源点到被标记顶点还能增加多少流量:第二用来分别个标记指出另一个顶点的名字,就是从该顶点访问到被标记顶点的(对于源点来说这个标记可以不必指定).方便起见,也可以为第二个标记加上“+”或“-”符号,用来分别指出该顶点是通过前向边还是后向边访问到的.因此,源点可被标记为∞,-.对于其他顶点,按照以下方法计算它的标记: (1)如果为标记顶点j是由j到

【codevs1907】方格取数3(最大流最小割定理)

网址:http://codevs.cn/problem/1907/ 题意:在一个矩阵里选不相邻的若干个数,使这些数的和最大. 我们可以把它看成一个最小割,答案就是矩阵中的所有数-最小割.先把矩阵按国际象棋棋盘黑白染色(即把相邻的点分别染成白色和黑色),然后黑点连源点,白点连汇点.割掉一个点到源/汇的边就是不选择这个点,最后的目的就是使源到汇不连通(不引发题目不能选择位置相邻的数的矛盾). 然而最小割怎么求呢? 于是我们就要引入一个定理:最大流最小割定理.它的意思就是说,在一个图中,a点到b点的最

poj3469(最大流最小割问题)

题目链接:http://poj.org/problem?id=3469 Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 18147   Accepted: 7833 Case Time Limit: 5000MS Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chi

最大流最小割算法

图像分割中用到最小割原理,引出了最大流最小割算法,主要参考来自UCLA CIVS的Hong Chen的PPT <Introduction to Min-Cut/Max-Flow Algorithms> 一. 首先借用PPT的两张图分别讲述一下两者的应用 1. 最大流应用于网络传输 2. 最小割应用于桥问题 二.基本概念之 s-t 图 1. 源结点(source node)和汇结点(sink node) 2. 从结点i到结点j的有向边(Arc)<i, j> 3. 每条边<i,

网络流(三)最大流最小割定理

转载:https://blog.csdn.net/w417950004/article/details/50538948 割(CUT)是网络中顶点的划分,它把网络中的所有顶点划分成两个顶点的集合源点S和汇点T.记为CUT(S,T). 如下图:源点:s=1;汇点:t=5.框外是容量,框内是流量 如下图是一个图的割.顶点集合S={1,2,3}和T={4,5}构成一个割. 如果一条弧的两个顶点分别属于顶点集S和T那么这条弧称为割CUT(S,T)的一条割边.  从S指向T的割边是正向割边,从T指向S的割

hihoCoder1378 (最大流最小割)

#1378 : 网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c(u,v).网络流的最大流问题求解的就是从s到t最多能有多少流量. 小Hi:那这个问题解决办法呢? 小Ho:解决网络流的基本思路就是寻找增广路,不断更新残留网络.直到找不到新的增