zoukankan      html  css  js  c++  java
  • POJ 3801/HDU 3157 Crazy Circuits | 有下界的最小流

    题目:

    POJ最近总是炸

    所以还是用HDU吧http://acm.hdu.edu.cn/showproblem.php?pid=3157


    题解:

    题很长,但其实就是给个有源汇带下界网络流(+是源,-是汇),求最小流

    求法:

    1.模仿可行流建图,但是不加t到s的INF边

    2.跑最大流

    3.加t到sINF边

    4.跑最大流

    5.如果两次答案相加不等于sum,无解;

    6.如果有解,t到s的反边流量就是答案

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define N 205
    #define M 20005
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,m,s,t,S,T,c,cur[N],head[N],d[N],sum,ecnt=1,ans,lev[N];
    char a[N],b[N];
    queue<int> q;
    struct adj
    {
        int nxt,v,w;
    }e[M];
    int calc(char j[])
    {
        if (j[0]=='+') return n+1;
        if (j[0]=='-') return n+2;
        int ans=0,s=strlen(j);
        for (int i=0;i<s;i++) ans*=10,ans+=j[i]-'0';
        return ans;
    }
    void add(int u,int v,int w)
    {
        e[++ecnt].v=v;e[ecnt].w=w;e[ecnt].nxt=head[u];head[u]=ecnt;
        e[++ecnt].v=u;e[ecnt].w=0;e[ecnt].nxt=head[v];head[v]=ecnt;
    }
    void init()
    {
        memset(head,0,sizeof(head));
        memset(d,0,sizeof(d));
        ecnt=1;ans=sum=0;
    }
    bool bfs()
    {
        for (int i=1;i<=T;i++)
            cur[i]=head[i],lev[i]=-1;
        q.push(S);lev[S]=1;
        while (!q.empty())
        {
            int u=q.front();q.pop();
            for (int i=head[u],v;i;i=e[i].nxt)
                if (lev[v=e[i].v]==-1 && e[i].w>0)
                    q.push(v),lev[v]=lev[u]+1;
        }
        return lev[T]!=-1;
    }
    int dfs(int u,int flow)
    {
        if (u==T) return flow;
        int ret=0,v,delta;
        for (int &i=cur[u];i;i=e[i].nxt)
            if (lev[v=e[i].v]==lev[u]+1 && e[i].w>0)
            {
                delta=dfs(v,min(flow-ret,e[i].w));
                if (delta)
                {
                    e[i].w-=delta;e[i^1].w+=delta;ret+=delta;
                    if (ret==flow) break;
                }
            }
        return ret;
    }
    int main()
    {
        while (scanf("%d%d",&n,&m)!=EOF)
        {
        if (n==0 && m==0) break;
        init();
        s=n+1;t=s+1;S=t+1;T=S+1;
        for (int i=1,u,v;i<=m;i++)
        {
            scanf("%s%s%d",a,b,&c);
            u=calc(a);v=calc(b);
            add(u,v,INF-c);
            d[u]-=c;d[v]+=c;
        }
        for (int i=1;i<=n+2;i++)
            if (d[i]>0) add(S,i,d[i]),sum+=d[i];
            else if (d[i]<0) add(i,T,-d[i]);
        while (bfs()) ans+=dfs(S,INF);
        add(t,s,INF);
        while (bfs()) ans+=dfs(S,INF);
        if (ans!=sum) puts("impossible");
        else printf("%d
    ",e[ecnt].w);
        }
        return 0;
    }
  • 相关阅读:
    Golang Struct 声明和使用
    docker 中ulimit设置理解
    微服务架构引入的问题及解决方案
    Jenkins 集成Sonar代码质量扫描
    Jenkins和gitlab集成自动构建
    初识微服务架构
    jenkins 集成钉钉机器人通知
    Go 新起点
    shell中的(),{}几种语法用法
    二进制日志配置和运维管理
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8227964.html
Copyright © 2011-2022 走看看