最大流最小割——hihoCoder 1378
来源:互联网 发布:python wxpython 安装 编辑:程序博客网 时间:2024/06/05 18:39
题目链接:
https://hihocoder.com/problemset/problem/1378分析:
给出一个已经建立好的网络流图,这个图中的点被最小割分成两个部分S集合(包括源点)和T集合(包括汇点)题解:
先跑一边最大流,然后从源点开始BFS,如果搜到有边的容量还有剩余就加入S集合。因为最小割的边一定是满流的。AC代码:
/************************************************************************* > File Name: test.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com ************************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cmath>#include <vector>#include <set>#include <list>#include <ctime>typedef long long LL;typedef unsigned long long ULL;typedef long double LD;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define Sqr(a) ((a)*(a))using namespace std;#define MaxN 666#define MaxM 41234#define INF 0x3f3f3f3f#define bug cout<<88888888<<endl;#define MIN(x,y) (x<y?x:y)#define MAX(x,y) (x>y?x:y)int N,M; //N个点,M条边struct Edge{ int u,v,next; int flow;}edge[MaxM]; //最大边数,一般都是实际边数的2倍甚至以上int head[MaxN];int cont;void init(){ //记得init cont = 0; MST(head, -1);}void add(int u, int v, int flow){ edge[cont].u = u; edge[cont].v = v; edge[cont].flow = flow; edge[cont].next = head[u]; head[u] = cont++;}void Add(int u, int v, int flow){ //建正反两条边,反向流量为0 add(u, v, flow); add(v, u, 0);}int dis[MaxN];int num[MaxN];int cur[MaxN];int pre[MaxN];set<int> ans;bool flag;void BFS(int source,int sink){ queue<int>q; CLR(num); MST(dis,-1); q.push(sink); dis[sink]=0; num[0]=1; if(flag) ans.insert(sink); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].v; if(flag) { if(dis[v] == -1 && edge[i].flow) { dis[v] = dis[u] + 1; num[dis[v]]++; q.push(v); ans.insert(v); } } else { if(dis[v] == -1) { dis[v] = dis[u] + 1; num[dis[v]]++; q.push(v); } } } }}int ISAP(int source,int sink,int n) //从源点到汇点,n为总点数,返回最大流{ memcpy(cur,head,sizeof(cur)); int flow=0, u = pre[source] = source; BFS( source,sink); while( dis[source] < n ) { if(u == sink) { int df = INF, pos; for(int i =source;i != sink;i = edge[cur[i]].v) { if(df > edge[cur[i]].flow) { df = edge[cur[i]].flow; pos = i; } } for(int i = source;i != sink;i = edge[cur[i]].v) { edge[cur[i]].flow -= df; edge[cur[i]^1].flow += df; } flow += df; //cout << flow << endl; u = pos; } int st; for(st = cur[u];st != -1;st = edge[st].next) { if(dis[edge[st].v] + 1 == dis[u] && edge[st].flow) { break; } } if(st != -1) { cur[u] = st; pre[edge[st].v] = u; u = edge[st].v; } else { if( (--num[dis[u]])==0 ) break; int mind = n; for(int id = head[u];id != -1;id = edge[id].next) { if(mind > dis[edge[id].v] && edge[id].flow != 0) { cur[u] = id; mind = dis[edge[id].v]; } } dis[u] = mind+1; num[dis[u]]++; if(u!=source) u = pre[u]; } } return flow;}int u,v,w;int main(){ while( ~scanf("%d%d", &N, &M)) { flag = false; init(); ans.clear(); for(int i=0;i<M;i++) { scanf("%d%d%d", &u, &v, &w); Add(u,v,w); } int S = 1, T = N; cout << ISAP(1,N,N); flag=true; BFS(N,1); printf(" %d\n", ans.size()); for(int x:ans)printf("%d ",x); printf("\n"); } //system("pause");}
0 0
- 最大流最小割——hihoCoder 1378
- 最大流—最小割
- hihocoder 网络流二·最大流最小割定理
- 网络流二·最大流最小割定理 HihoCoder
- hihocoder 1378 : 网络流二·最大流最小割定理
- hihocoder 1378 网络流二·最大流最小割定理
- 最大流/最小割
- 最大流最小割
- 最大流最小割
- 最大流最小割
- 最大流最小割
- hihoCoder 1378 网络流二·最大流最小割定理 (网络流学习#2 记录)
- 网络流(1)——最大流、最小割
- hdu4289——Control(最大流最小割+SAP)
- poj 3308 Paratroopers 最小割—最大流
- 最大流—最小割的C++实现
- 最大流最小割定理
- 最大流-最小割简介
- 尝试将I/O流 用一张图来表示
- windbg设断点命令详解(bp, bu, bm, ba 以及bl, bc, bd, be)
- 关于ORB_SLAM2在Ubuntu16.04下编译出错的解决办法之一
- Android学习之 VideoView,SurfaceView 资源
- 2016年3月最新苹果上线流程
- 最大流最小割——hihoCoder 1378
- Android报错:调用so库时“xxx.so has text relocations”
- sql 注入方式
- java中静态代码快的用法
- G-Dancing Stars on Me(2015ACM-ICPC长春站)
- 从零开始Android NDK 开发(一)
- iOS访问https无数据,访问http正常
- 输入中含有大写字母就会转换为小写字母,其它字符不变
- 利用windbg探索进程和进程上下文