首页 > 代码库 > hust 1230 beautiful

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\n");
        else
        {
            Edge temp=edges[m-2];
            printf("%d\n",temp.flow);
        }
    }
    return 0;
}

作者 chensunrise