永远不可能学会的图论之网络流

                                                Water

                                                              时间限制: 1 Sec  内存限制: 128 MB
                                                                            提交: 72  解决: 18
                                                             [提交] [状态] [讨论版] [命题人:admin]

题目描述

A water company is trying to provide water from its pumping station to a mansion. The company owns n water stations, numbered 1..n, which are connected by a variety of pipes. Water can flow through both directions of a pipe, but the total amount of water that can flow through the pipe is bounded by the capacity of the pipe.
The water company is constantly improving the pipes, increasing the capacity of various pipes. The water company is conducting k improvements (each of which is permanent after it is executed). An improvement consists of taking a pipe between two locations and increasing its capacity by a fixed amount, or installing a pipe between two locations which are not directly connected by a pipe.
After each improvement, the water company wants to know the maximum amount of water the mansion could receive.

输入

Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. The first line of input contains three integers, n (2≤n≤100), p (0≤p≤ n(n-1)/2), and k (1≤k≤10,000), where n is the number of stations, p is the number of initial pipes, and k is the number of improvements. The first station in the list is always the pumping station, and the second is always the mansion.
The next p lines will describe the pipes in the initial setup. The lines will each contain three integers, a, b (1≤a<b≤n) and c (1≤c≤1,000), which indicates that stations a and b are connected by a pipe with capacity c. No (a,b) pair will appear more than once in this section.
The next k lines will describe the improvements. The lines will each contain three integers, a, b (1≤a<b≤n) and c (1≤c≤1,000), which indicates that the pipe connecting stations a and b has its capacity increased by c (if there is currently no pipe between a and b, then one is created with capacity c). Note that it is possible for an (a,b) pair to be repeated in this section.

输出

Output k+1 integers, each on its own line, describing the maximum amount of water that can reach the mansion. The first number is the amount of water reaching the mansion in the initial configuration. The next k numbers are the amounts of water reaching the mansion after each improvement.

样例输入

3 2 1
1 3 10
2 3 1
2 3 15

样例输出

1
10

                                                                               [提交]          [状态]

【解析】;这题套网络流dinic跑最大流应该是没问题的,但超时很拿人。竟然还有这种优化。

cur数组可以说是大功臣,有了这个数组,立马不超时了。cur数组的作用是记录dfs时,扫描的起始点,不必每次都从1开始扫描,而是从cur[u]开始!

这是第一次敲关于网络流的问题,,,,,还算有所收获

来自acm大佬的解析

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <utility>
#include <time.h>
#include <set>
#include <bitset>
#include <vector>
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define ll long long
const int maxn=1e5+5;
using namespace std;
int n,m,k;
int dep[300];
int mmp[300][300];
int cur[300];
int bfs(int s,int t)
{
    ms(dep,-1);
    dep[s]=0;
    queue<int> q;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        if(u==t)return 1;
        for(int i=0;i<=n;i++)
        {
            if(dep[i]<0 && mmp[u][i])
            {
                dep[i]=dep[u]+1;
                q.push(i);
            }
        }
    }
    if(dep[t]<0)return 0;
    return 1;
}
int dfs(int s,int t,int low=INF)
{
    if(s==t)return low;
    int cap;
    for(int &v=cur[s];v<=n;v++)
    {
        if(mmp[s][v] && dep[v]==dep[s]+1 && (cap=dfs(v,t,min(low,mmp[s][v]))))
        {
            mmp[s][v]-=cap;
            mmp[v][s]+=cap;
            return cap;
        }
    }
    return 0;
}
int dinic(int s,int t)
{

    int temp,ans=0;
    while(bfs(s,t))
    {
    	for(int i=1;i<=n;i++)cur[i]=1;
        ans+=dfs(s,t);
    }
    return ans;

}
int main()
{
    int s,t,l;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)//m边,n点
    {
        ms(mmp,0);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&s,&t,&l);
            mmp[s][t]=l;
			mmp[t][s]=l;

        }

        int ans=dinic(1,2);
       	printf("%d\n",ans);
        while(k--)
        {

            scanf("%d%d%d",&s,&t,&l);
            mmp[s][t]+=l;
			mmp[t][s]+=l;
	        ans+=dinic(1,2);
	        printf("%d\n",ans);
		}
    }

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图论网络理论是计算机科学领域中的两个重要的理论分支。图论是研究研究图结构以及与其相关的性质和算法的学科。图由节点和边组成,节点表示对象,边表示对象之间的联系或关系。图论主要关注的问题包括图的连通性、路径问题、最短路径等。在计算机网络、社交网络等领域中广泛应用。 而网络理论是研究物质或信息在网络中从源节点到汇节点传递的问题。这个问题可以转化为在图中找出满足一定约束条件下的最大或最小割等问题。网络理论可以应用于很多领域,如计算机网络中的路由优化、货物配送中的路径选择、电力网络的负载均衡等。 对于图论网络理论来说,一些经典的算法非常重要且有实际应用。比如最短路径算法(如Dijkstra算法和Bellman-Ford算法)、最大最小割算法(如Ford-Fulkerson算法和Edmonds-Karp算法)等。这些算法能够帮助我们解决在图和网络中的各种问题。 对于图论网络理论的学习,可以通过阅读相关的资料,如图论网络理论的授课教材、论文以及相应的pdf文档。这些资料可以帮助我们了解关键的概念、算法和应用领域。通过理论学习,我们可以将其应用于实际问题中,并设计出高效的解决方案。 总之,图论网络理论是计算机科学领域中重要的理论分支。它们的理论基础和算法应用广泛,能够帮助我们解决各种与图和网络相关的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值