zoukankan      html  css  js  c++  java
  • bzoj千题计划228:bzoj2095: [Poi2010]Bridges

    http://www.lydsy.com/JudgeOnline/problem.php?id=2095

    二分答案,判断是否存在混合图的欧拉回路

    如果只有一个方向的风力<=mid,这条边就是单向边

    如果两个方向的风力都<=mid,这条边就是双向边

    如果两个方向的风力都>mid,这条边不可能被经过,mid不合法

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 1003 
    #define M 6001
    
    int n,m;
    struct node
    {
        int u,v,a,b;
    }e[2001];
    
    int src,decc;
    int tot,front[N],nxt[M],to[M],cap[M];
    int lev[N],cur[N];
    queue<int>q;
    
    int d[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; cap[tot]=w;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; cap[tot]=0;
    }
    
    bool bfs()
    {
        int now,t;
        for(int i=0;i<=decc;++i) lev[i]=-1,cur[i]=front[i];
        lev[src]=0;
        q.push(src);
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            for(int i=front[now];i;i=nxt[i])
            {
                t=to[i];
                if(lev[t]==-1 && cap[i])
                {
                    lev[t]=lev[now]+1;
                    q.push(t);
                }
            }
        }
        return lev[decc]!=-1;
    }
    
    int dinic(int now,int flow)
    {
        if(now==decc) return flow;
        int rest=0; int delta,t;
        for(int &i=cur[now];i;i=nxt[i])
        {
            t=to[i];
            if(lev[t]==lev[now]+1 && cap[i])
            {
                delta=dinic(t,min(cap[i],flow-rest));
                if(delta)
                {
                    rest+=delta;
                    cap[i]-=delta;
                    cap[i^1]+=delta;
                    if(rest==flow) break;
                }
            }
        }
        if(rest!=flow) lev[now]=-1;
        return rest;
    }
    
    bool check(int mid)
    {
        memset(d,0,sizeof(d));
        for(int i=1;i<=m;++i)
        {
            if(e[i].a<=mid && e[i].b>mid) d[e[i].u]++,d[e[i].v]--;
            else if(e[i].b<=mid && e[i].a>mid) d[e[i].v]++,d[e[i].u]--;
            else if(e[i].a<=mid && e[i].b<=mid) d[e[i].u]++,d[e[i].v]--;
            else return false;
        }
        for(int i=1;i<=n;++i)
            if(d[i]&1) return false;
        int sum=0;
        tot=1;
        memset(front,0,sizeof(front));
        for(int i=1;i<=n;++i)
            if(d[i]>0) add(src,i,d[i]/2),sum+=d[i]/2;
            else if(d[i]<0) add(i,decc,-d[i]/2);
        for(int i=1;i<=m;++i)
            if(e[i].a<=mid && e[i].b<=mid) add(e[i].u,e[i].v,1);
        int max_flow=0;
        while(bfs()) 
            max_flow+=dinic(src,1e8);
        return max_flow==sum;
    }
    
    int main()
    {
        read(n); read(m);
        decc=n+1;
        for(int i=1;i<=m;++i)
        {
            read(e[i].u); read(e[i].v); read(e[i].a); read(e[i].b);
        }
        int l=1,r=1000,mid,ans=0;
        while(l<=r)
        {
            mid=l+r>>1;
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        if(ans) printf("%d",ans);
        else printf("NIE");
        return 0;
    }
  • 相关阅读:
    封装了一个简单的筛选菜单控件
    安卓存储资源
    处理webp加所有的jpg到指定路径
    苹果内购
    JavaScript关于md5加密
    JavaScript关于sha1加密
    h5跳转
    python遍历文件(替换)
    python遍历文件
    安卓点击home键重启
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8425201.html
Copyright © 2011-2022 走看看