题目大意:
就是给出一个DAG, 源点是1, 汇点是M, 给出每条边的容量, 询问1到M的最大流
大致思路:
网络流模板题...
第一次写网络流, 记一下
代码如下:
Result : Accepted Memory : 1576 KB Time : 0 ms
/* * Author: Gatevin * Created Time: 2015/12/4 22:08:42 * File Name: Yukinoshita_Yukino.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; /* * 第一道网络流的题 * 使用Dinic模板 */ #define maxn 222 //maxn : 点数 #define maxm 222 //maxm : 无向边边数 struct Edge//有向边u->v容量是cap { int u, v, nex, cap; Edge(){} Edge(int _u, int _v, int _nex, int _cap) { u = _u, v = _v, nex = _nex, cap = _cap; } }; Edge edge[maxm << 1]; int E; int head[maxn]; void add_Edge(int u, int v, int c)//第一条边下标必须是偶数 { edge[++E] = Edge(u, v, head[u], c); head[u] = E; edge[++E] = Edge(v, u, head[v], 0); head[v] = E; } int N, M; int dep[maxn]; bool bfs(int start, int end) { int Q[maxn]; int l, r; l = r = 0; memset(dep, -1, sizeof(dep)); Q[r++] = start; dep[start] = 0; while(l != r) { int u = Q[l++]; if(l == maxn) l = 0; for(int i = head[u]; i + 1; i = edge[i].nex) { int v = edge[i].v; if(edge[i].cap > 0 && dep[v] == -1) { dep[v] = dep[u] + 1; Q[r++] = v; if(r >= maxn) r = 0; if(v == end) return 1; } } } return 0; } int dinic(int start, int end) { int res = 0; int top; int stack[maxn];//stack为存储当前增广路的栈 int cur[maxn]; while(bfs(start, end))//存在增广路就继续增广 { memcpy(cur, head, sizeof(head)); int u = start; top = 0; while(1) { if(u == end)//对增广路上的流量做减法并且对反向边容量进行扩张 { //int min = INF; int min = 1e9; int loc; for(int i = 0; i < top; i++) if(min > edge[stack[i]].cap) { min = edge[stack[i]].cap; loc = i; } for(int i = 0; i < top; i++) { edge[stack[i]].cap -= min; edge[stack[i] ^ 1].cap += min; } res += min; top = loc; u = edge[stack[top]].u; } for(int i = cur[u]; i + 1; cur[u] = i = edge[i].nex) if(edge[i].cap != 0 && dep[u] + 1 == dep[edge[i].v])//寻找是否有往下一层的路 break; if(cur[u] != -1)//有下一层的路 { stack[top++] = cur[u]; u = edge[cur[u]].v; } else//不能继续向下走了, 回溯 { if(top == 0) break; dep[u] = -1; u = edge[stack[--top]].u; } } } return res; } int main() { while(scanf("%d %d", &N, &M) != EOF) { memset(head, -1, sizeof(head)); E = -1; int u, v, c; for(int i = 0; i < N; i++) { scanf("%d %d %d", &u, &v, &c); add_Edge(u, v, c); } printf("%d\n", dinic(1, M)); } return 0; }