• 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

    至少做到我努力了
  • 相关阅读:
    前端知识---html
    Python3中的运算符
    Python中的print、input函数以及Python中交换两个变量解析
    我的第一个Python程序,定义主函数,eval、format函数详解,
    MySQL创建索引
    认识MySQL中的索引
    MySQL中的函数
    MySQL的查询语句
    MySQL中增删改操作
    MySQL中的运算符和时间运算
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3776978.html
Copyright © 2020-2023  润新知