hdu-3549 Flow Problem---最大流模板题(dinic算法模板)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3549

题目大意:

给有向图,求1-n的最大流

解题思路:

直接套模板,注意有重边

传送门:网络流入门

  1 #include<iostream>
  2 #include<vector>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<queue>
  6 using namespace std;
  7 const int INF = 0x3f3f3f3f;
  8 const int maxn = 50;
  9 int Map[maxn][maxn];
 10 struct edge
 11 {
 12     int u, v, c, f;
 13     edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){}
 14 };
 15 vector<edge>e;
 16 vector<int>G[maxn];
 17 int level[maxn];//BFS分层,表示每个点的层数
 18 int iter[maxn];//当前弧优化
 19 int m;
 20 void init(int n)
 21 {
 22     for(int i = 0; i <= n; i++)G[i].clear();
 23     e.clear();
 24 }
 25 void addedge(int u, int v, int c)
 26 {
 27     e.push_back(edge(u, v, c, 0));
 28     e.push_back(edge(v, u, 0, 0));
 29     m = e.size();
 30     G[u].push_back(m - 2);
 31     G[v].push_back(m - 1);
 32 }
 33 void BFS(int s)//预处理出level数组
 34 //直接BFS到每个点
 35 {
 36     memset(level, -1, sizeof(level));
 37     queue<int>q;
 38     level[s] = 0;
 39     q.push(s);
 40     while(!q.empty())
 41     {
 42         int u = q.front();
 43         q.pop();
 44         for(int v = 0; v < G[u].size(); v++)
 45         {
 46             edge& now = e[G[u][v]];
 47             if(now.c > now.f && level[now.v] < 0)
 48             {
 49                 level[now.v] = level[u] + 1;
 50                 q.push(now.v);
 51             }
 52         }
 53     }
 54 }
 55 int dfs(int u, int t, int f)//DFS寻找增广路
 56 {
 57     if(u == t)return f;//已经到达源点,返回流量f
 58     for(int &v = iter[u]; v < G[u].size(); v++)
 59         //这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历
 60         //在每次找增广路的时候,数组要清空
 61     {
 62         edge &now = e[G[u][v]];
 63         if(now.c - now.f > 0 && level[u] < level[now.v])
 64             //now.c - now.f > 0表示这条路还未满
 65             //level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想
 66         {
 67             int d = dfs(now.v, t, min(f, now.c - now.f));
 68             if(d > 0)
 69             {
 70                 now.f += d;//正向边流量加d
 71                 e[G[u][v] ^ 1].f -= d;
 72     //反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到
 73                 return d;
 74             }
 75         }
 76     }
 77     return 0;
 78 }
 79 int Maxflow(int s, int t)
 80 {
 81     int flow = 0;
 82     for(;;)
 83     {
 84         BFS(s);
 85         if(level[t] < 0)return flow;//残余网络中到达不了t,增广路不存在
 86         memset(iter, 0, sizeof(iter));//清空当前弧数组
 87         int f;//记录增广路的可增加的流量
 88         while((f = dfs(s, t, INF)) > 0)
 89         {
 90             flow += f;
 91         }
 92     }
 93     return flow;
 94 }
 95 int T, cases;
 96 int main()
 97 {
 98     cin >> T;
 99     while(T--)
100     {
101         int n, k;
102         cin >> n >> k;
103         init(n);
104         memset(Map, 0, sizeof(Map));
105         int u, v, c;
106         for(int i = 0; i < k; i++)
107         {
108             cin >> u >> v >> c;
109             Map[u][v] += c;
110         }
111         for(int i = 1; i <= n; i++)
112         {
113             for(int j = 1; j <= n; j++)
114             {
115                 if(!Map[i][j])continue;
116                 addedge(i, j, Map[i][j]);
117             }
118         }
119         cout<<"Case "<<++cases<<": ";
120         cout<<Maxflow(1, n)<<endl;
121     }
122     return 0;
123 }

 

posted @ 2018-04-16 19:17  _努力努力再努力x  阅读(219)  评论(0编辑  收藏  举报