zoukankan      html  css  js  c++  java
  • 计蒜客——排涝(基础最大流入门)

    • 1000ms
    • 65536K

    到了雨季农业生产的排涝就成了一个大问题。为了保证植物生长的顺利,某县政府决定投资为农田区建立一些排涝渠,将农田里多余的水排到小溪里。

    输入第1行包括用一个空格分隔的两个整数N和M,N表示县政府专家设计的排涝渠的数量,M是排涝渠交叉点的数量。其中第一个交点是农田区,交点M是小溪(0≤N≤200,2≤M≤200)。第2行-第N+1行中每行有三个用空格分隔的整数,Si、Ei和Ci。Si和Ei说明了排涝渠的端点,多余的水自Si流向Ei;Ci是这个第i条排涝渠的最大排水量。(1≤Si,Ei≤M,0≤Ci≤10000000)

    输出只有一个,为规划好的排涝渠的最大流量。

    样例输入

    5 4
    1 2 40
    1 4 20
    2 4 20
    2 3 30
    3 4 10 

    样例输出

    50
    题解:

    基础最大流入门题,这里我用的是Dinic算法。

    代码:

    #include <algorithm>
    #include <vector>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int MAXN = 205;
    
    struct Edge
    {
    	int to,value,rev;//rev用于存储反向边在E[to]中的下标。
    	Edge() {}
    	Edge(int a,int b,int c):to(a),value(b),rev(c) {}
    };
    
    vector<Edge> E[MAXN];
    int deep[MAXN];
    int iter[MAXN];//当前边优化 
    
    inline void Add(int from,int to,int value)//邻接表加入边 
    {
    	E[from].push_back(Edge(to,value,E[to].size()));
    	E[to].push_back(Edge(from,0,E[from].size()-1));
    }
    
    bool BFS(int root,int target)//广搜分层 
    {
    	memset(deep,-1,sizeof deep);
    	queue<int> Q;
    	deep[root] = 0;
    	Q.push(root);
    	while(!Q.empty())
    	{
    		int t = Q.front();
    		Q.pop();
    		for(int i=0 ; i<E[t].size() ; i++)
    		{
    			if(E[t][i].value > 0 && deep[E[t][i].to] == -1)
    			{
    				deep[E[t][i].to] = deep[t] + 1;
    				Q.push(E[t][i].to);
    			}
    		}
    	}
    	return deep[target] != -1;
    }
    
    int DFS(int root,int target,int flow)//深搜寻找增广路径 
    {
    	if(root == target)return flow;
    	for(int &i=iter[root] ; i<E[root].size() ; i++)
    	{
    		if(E[root][i].value>0 && deep[E[root][i].to] == deep[root]+1)
    		{
    			int nowflow = DFS(E[root][i].to,target,min(flow,E[root][i].value));
    			if(nowflow > 0)
    			{
    				E[root][i].value -= nowflow;
    				E[E[root][i].to][E[root][i].rev].value += nowflow;
    				return nowflow;
    			}
    		}
    	}
    	return 0;
    }
    
    int Dinic(int root,int target)
    {
    	int sumflow = 0;
    	while(BFS(root,target))
    	{
    		memset(iter,0,sizeof iter);
    		int mid;
    		while((mid=DFS(root,target,INF)) > 0)
    		{
    			sumflow += mid;
    		}
    	}
    	return sumflow;
    }
    
    int main()
    {
    
    	int N,M;
    	int s,e,c;
    	while(scanf("%d %d",&N,&M)!=EOF)
    	{
    		for(int i=0 ; i<N ; i++)
    		{
    			scanf("%d %d %d",&s,&e,&c);
    			Add(s,e,c);
    		}
    		printf("%d
    ",Dinic(1,M));
    	}
    
    
    	return 0;
    }
    

  • 相关阅读:
    apply call bind方法的区别和含义
    html头部meta标签
    语义化标签
    “文件名和url路径名”命名要点以及大小写问题
    BMP GIF PNG JPG等图片格式的区别和适用情况
    前端页面的性能优化
    js阻止默认事件,如a标签跳转和事件冒泡
    散列碰撞问题的解决——开链法(拉链法)
    substring()方法
    对学生成绩进行散列
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514091.html
Copyright © 2011-2022 走看看