zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第一场)I

    Description

    给定无向图 (n le 50, m le 100),求能否选出一些边使得第 (i) 个顶点恰好与 (d_i (1 le d_i le 2)) 条边相连。

    Solution (!Fake)

    (以下算法已被 hack,谨慎参考!)

    最大流

    原图结点 (i) 对应 (i,i'),边 (<a_i,b_i>) 对应 (a_i o b_i',b_i o a_i'),那么这条边被选中,对应的两条边都产生了流

    (S o i, i' o T),容量各为 (d_i)

    最后检查与最大流是否为 (sum d_i) 即可

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=50005;
    const int maxm=500005;
    const int inf=0x3f3f3f3f;
    struct Node{
        int to,val,next;
    }q[maxm<<1];
    int head[maxn],cnt=0,dep[maxn],cur[maxn],vis[maxn];
    int sp,ep,maxflow;
    void init(){
        memset(head,-1,sizeof(head));
        cnt=2,maxflow=0;
    }
    void addedge(int from,int to,int val){
        q[cnt].to=to;
        q[cnt].val=val;
        q[cnt].next=head[from];
        head[from]=cnt++;
    }
    void make(int from,int to,int val){
        addedge(from,to,val);
        addedge(to,from,0);
    }
    bool bfs(int n){
        for(int i=0;i<=n;i++){
            cur[i]=head[i],dep[i]=0x3f3f3f3f;
            vis[i]=0;
        }
        dep[sp]=0;
        queue<int>que;
        que.push(sp);
        while(!que.empty()){
            int x=que.front();
            que.pop();
            vis[x]=0;
            for(int i=head[x];i!=-1;i=q[i].next){
                int to=q[i].to;
                if(dep[to]>dep[x]+1&&q[i].val){
                    dep[to]=dep[x]+1;
                    if(!vis[to]){
                        que.push(to);
                        vis[to]=1;
                    }
                }
            }
        }
        if(dep[ep]!=inf) return true;
        else return false;
    }
    int dfs(int x,int flow){
        int rlow=0;
        if(x==ep){
            maxflow+=flow;
            return flow;
        }
        int used=0;
        for(int i=cur[x];i!=-1;i=q[i].next){
            cur[x]=i;
            int to=q[i].to;
            if(q[i].val&&dep[to]==dep[x]+1){
                if(rlow=dfs(to,min(flow-used,q[i].val))){
                    used+=rlow;
                    q[i].val-=rlow;
                    q[i^1].val+=rlow;
                    if(used==flow) break;
                }
            }
        }
        return used;
    }
    int dinic(int n){
        while(bfs(n)){
            dfs(sp,inf);
        }
        return maxflow;
    }
    signed main()
    {
        int n,m;
        while(cin>>n>>m)
        {
            init();
            int d[105];
            int sum=0;
            for(int i=1;i<=n;i++) cin>>d[i], sum+=d[i];
            int t1,t2;
            for(int i=1;i<=n;i++) make(2*n+1,i,d[i]), make(i+n,2*n+2,d[i]);
            for(int i=1;i<=m;i++)
            {
                cin>>t1>>t2;
                make(t1,t2+n,1);
                make(t2,t1+n,1);
            }
            sp=2*n+1;
            ep=2*n+2;
            cout<<(dinic(2*n+2)==sum ? "Yes" : "No")<<endl;
        }
    }
    
    
  • 相关阅读:
    4、pytest -- fixtures:明确的、模块化的和可扩展的
    CentOS -- 新建用户并使能密钥登录
    3、pytest -- 编写断言
    2、pytest -- 使用和调用
    1、pytest -- 安装和入门
    《Fluent Python》 -- 一个关于memoryview例子的理解过程
    SecureCRT 连接 Centos7.0 (NAT模式),且能连接公网。
    SecureCRT 连接 Centos7.0 (桥接模式),且能连接公网。
    Centos7.0 三种网络适配器
    Centos 7.0 界面
  • 原文地址:https://www.cnblogs.com/mollnn/p/13300145.html
Copyright © 2011-2022 走看看