• hdu3572


    题解:

    网络流

    判断是否为漫流

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    const int INF=1e9,N=2500,M=400005,FIN=2015;
    typedef long long ll;
    int n,m,s,t,sum,ec,head[N],first[N],que[N],lev[N],Next[M],to[M],v[M];
    void init()
    {
        sum=ec=0;
        memset(first,-1,sizeof(first));
        s=0,t=FIN;
    }
    void addEdge(int a,int b,int c) 
    {
        to[ec]=b;
        v[ec]=c;
        Next[ec]=first[a];
        first[a]=ec++;
        to[ec]=a;
        v[ec]=0;
        Next[ec]=first[b];
        first[b]=ec++;
    }
    int BFS() 
    {
        int kid,now,f=0,r=1;
        memset(lev,0,sizeof(lev));
        que[0]=s,lev[s]=1;
        while (f<r)
         {
            now=que[f++];
            for (int i=first[now];i!=-1;i=Next[i])
             {
                kid=to[i];    
                if (!lev[kid]&&v[i])
                 {
                    lev[kid]=lev[now]+1;    
                    if (kid==t)return 1;
                    que[r++]=kid;
                 }
             }
         }
        return 0;
    }
    int DFS(int now, int sum) 
    {
        int kid,flow,rt=0;
        if (now==t) return sum;
        for (int i=head[now];i!=-1&&rt<sum;i=Next[i])
         {
            head[now]=i;  
            kid=to[i];
            if (lev[kid]==lev[now]+1&&v[i])
             {
                flow=DFS(kid,min(sum-rt,v[i]));
                if (flow)
                 {
                    v[i]-=flow;
                    v[i^1]+=flow;
                    rt+=flow;
                 }
                else lev[kid]=-1;   
             }           
         }
        return rt;
    }
    int dinic() 
    {
        int ans=0;
        while (BFS())
         {
            for (int i=0;i<=t;i++)head[i]=first[i]; 
            ans+=DFS(s,INF);
         }
        return ans;
    }   
    void input() 
    {
        int Min=INF,Max=0;
        scanf("%d%d",&n,&m);
        int a,b,c;
        for (int i=1;i<=n;i++)
         {
            scanf("%d%d%d",&a,&b,&c);  
            sum+=a;
            addEdge(s,i,a);
            for (int j=b;j<=c;j++)addEdge(i,j+n,1);   
            if (c<b)swap(c,b);
            if (Min>b)Min=b;
            if (Max<c)Max=c;
         }
        for (int i=Min;i<=Max;i++)addEdge(i+n,t,m);   
    }
    int main() 
    {
        int T,Case=1;
        scanf("%d",&T);
        while (T--)
         {
            printf("Case %d: ",Case++);
            init();
            input();
            if (dinic()==sum) puts("Yes");
            else puts("No");
            puts("");
         }
        return 0;
    }
  • 相关阅读:
    Word操作——通配符
    圆的拟合
    最优化案例整理
    机器学习数学基础知识备忘
    scikit-learn学习笔记
    Linux下安装scikit-learn
    ROS学习备忘
    [ROS]激光驱动安装
    CMake和Linux编程:find_package的使用
    [OpenCV]直线拟合
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8421324.html
Copyright © 2020-2023  润新知