zoukankan      html  css  js  c++  java
  • hust 1230 beautiful

    题目描述

    Timy is visiting a beautiful park. There are M rivers and N lakes(marked 1-N), any two lakes are connected by at most one river. He knows that the ith river had to have water flowed with speed in the range [li,ri] to make the park beautiful . The staff will pour water in one lake (lake marked 1) and only one lake (lake marked N) connected to the outside from which the water will flow away. To save water , Timy wants to know what's the minimal speed for the staff to pour water in order to make the park beautiful .

    输入

    The input contains several test cases. For each test case Two positive integer numbers N (1 <= N <= 60) and M (0 < M <= N^2) have been written in the first line - number of lakes and rivers. There are M lines follows: each line contains four integer numbers fi, ti, li, ri (fi!=ti , 0 < fi,ti <= N, 0 <= li <= ri < 10000); the numbers are separated by space indicate the ith river flow from fi to ti and the range of speed is [li,ri].

    输出

    Write one integer number for each test case - it ought to be the minimal speed of add water. If it is impossible to make the park beautiful, write "Impossible".

    样例输入

    4 4
    1 2 0 2
    2 4 1 1
    1 3 2 2
    3 4 0 3
    4 4
    1 2 0 1
    2 4 2 2
    1 3 3 3
    3 4 0 2
    

    样例输出

    3
    Impossible

    这个题目,知道网络流的人,一看就知道是一道有流量上下界的最小流问题
    解法,添加一个超级源点和一个超级汇点,构造出一个只含有自由流和必须流的图,求源汇点的最大流flow1,再添加一条从n到1的容量为inf的边,再求一次最大流flow2,这时候就可以判断了,若flow1+flow2==总的必须流,那么有解,解就是n到1的流量,否则无解,这样就避免了做删边的操作,而且简单多了,时间效率也不错
    #include<map>
    #include<set>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define  inf 0x0f0f0f0f
    
    using namespace std;
    
    const double pi=acos(-1.0);
    const double eps=1e-8;
    typedef pair<int,int>pii;
    
    const int maxn=60+10;
    
    struct Edge
    {
        int from,to,cap,flow;
    };
    
    int n,m,s,t;
    vector<Edge>edges;
    vector<int>G[maxn];
    int d[maxn],cur[maxn];
    bool vis[maxn];
    
    void AddEdge(int from,int to,int cap)
    {
        Edge temp;
        temp.cap=cap; temp.flow=0; temp.from=from; temp.to=to;
        edges.push_back(temp);
        temp.cap=0; temp.flow=0; temp.from=to; temp.to=from;
        edges.push_back(temp);
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty())
        {
            int x=Q.front();Q.pop();
            for (int i=0;i<G[x].size();i++)
            {
                Edge& e=edges[G[x][i]];
                if (!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    int DFS(int x,int a)
    {
        if (x==t || a==0) return a;
        int flow=0,f;
        for (int& i=cur[x];i<G[x].size();i++)
        {
            Edge& e=edges[G[x][i]];
            if (d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if (a==0) break;
            }
        }
        return flow;
    }
    
    int Dinic()
    {
        int flow=0;
        while (BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,inf);
        }
        return flow;
    }
    
    void init()
    {
        for (int i=0;i<=maxn;i++) G[i].clear();
        edges.clear();
    }
    
    int main()
    {
        int N,M,indegree[maxn],outdegree[maxn],x,y,down,up,sum;
        while(scanf("%d%d",&N,&M)!=EOF)
        {
            memset(indegree,0,sizeof(indegree));
            memset(outdegree,0,sizeof(outdegree));
            sum=0;
            n=N+2;
            init();
            for (int i=0;i<M;i++)
            {
                scanf("%d%d%d%d",&x,&y,&down,&up);
                AddEdge(x,y,up-down);
                indegree[y]+=down;
                outdegree[x]+=down;
            }
            for (int i=1;i<=N;i++)
            {
                int mi=indegree[i]-outdegree[i];
                if (mi>0) AddEdge(0,i,mi);
                if (mi<0) {AddEdge(i,N+1,-mi);sum+=(-mi);}
            }
            s=0; t=N+1;
            //AddEdge(N,1,inf);
            int ans1=Dinic();
            AddEdge(N,1,inf);
            int ans2=Dinic();
            if (ans1+ans2!=sum) printf("Impossible
    ");
            else
            {
                Edge temp=edges[m-2];
                printf("%d
    ",temp.flow);
            }
        }
        return 0;
    }

    作者 chensunrise

    至少做到我努力了
  • 相关阅读:
    通过代码学REST之二——Restlet框架学习
    页面解析工具:HtmlParser学习
    游标的使用
    软件测试工具杂谈
    XUL资料
    MYSQL5.1修改表名与复制表结构的定时器与存储过程
    mysql 5.7以上版本下载及安装
    AnyChart图表控件(一)简介
    AnyChart图表控件(二)优势
    踩坑 Pycharm 2020.1.1 安装/ JetBrains破解/ anacode配置
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3776978.html
Copyright © 2011-2022 走看看