zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (上下界网络流)

    正解:

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAXN=10010;//点数的最大值
    const int MAXM=400010;//边数的最大值
    #define captype int
    
    struct SAP_MaxFlow{
        struct EDGE{
            int to,next;
            captype cap;
        }edg[MAXM];
        int eid,head[MAXN];
        int gap[MAXN];
        int dis[MAXN];
        int cur[MAXN];
        int pre[MAXN];
    
        void init(){
            eid=0;
            memset(head,-1,sizeof(head));
        }
        void AddEdge(int u,int v,captype c,captype rc=0){
            edg[eid].to=v; edg[eid].next=head[u];
            edg[eid].cap=c;  head[u]=eid++;
            edg[eid].to=u; edg[eid].next=head[v];
            edg[eid].cap=rc; head[v]=eid++;
        }
        captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意
            memset(gap,0,sizeof(gap));
            memset(dis,0,sizeof(dis));
            memcpy(cur,head,sizeof(head));
            pre[sNode] = -1;
            gap[0]=n;
            captype ans=0;
            int u=sNode;
            while(dis[sNode]<n){
                if(u==eNode){
                    captype Min=INF ;
                    int inser;
                    for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to])
                    if(Min>edg[i].cap){
                        Min=edg[i].cap;
                        inser=i;
                    }
                    for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]){
                        edg[i].cap-=Min;
                        edg[i^1].cap+=Min;
                    }
                    ans+=Min;
                    u=edg[inser^1].to;
                    continue;
                }
                bool flag = false;
                int v;
                for(int i=cur[u]; i!=-1; i=edg[i].next){
                    v=edg[i].to;
                    if(edg[i].cap>0 && dis[u]==dis[v]+1){
                        flag=true;
                        cur[u]=pre[v]=i;
                        break;
                    }
                }
                if(flag){
                    u=v;
                    continue;
                }
                int Mind= n;
                for(int i=head[u]; i!=-1; i=edg[i].next)
                if(edg[i].cap>0 && Mind>dis[edg[i].to]){
                    Mind=dis[edg[i].to];
                    cur[u]=i;
                }
                gap[dis[u]]--;
                if(gap[dis[u]]==0) return ans;
                dis[u]=Mind+1;
                gap[dis[u]]++;
                if(u!=sNode) u=edg[pre[u]^1].to;  //退一条边
            }
            return ans;
        }
    }F;
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int cas = 1;
        int N,M,K,u,v;
        while(scanf("%d %d %d",&N,&M,&K)==3){
            int L,R; scanf("%d %d",&L,&R);
            F.init();
            int s= 0,t = N+M+1;
            int S = N+M+2,T = N+M+3;
            F.AddEdge(t,s,INF);
            F.AddEdge(s,T,L*N);
            F.AddEdge(S,t,L*M);
            for(int i=1;i<=N;++i) F.AddEdge(s,i,R-L), F.AddEdge(S,i,L);
            for(int i=1;i<=M;++i) F.AddEdge(i+N,t,R-L),F.AddEdge(i+N,T,L);
            while(K--){
                scanf("%d %d",&u,&v);
                F.AddEdge(u,v+N,1);
            }
            int f = F.maxFlow_sap(S,T,N+M+4);
    
    
            printf("Case %d: ",cas++);
            if(f==(N+M)*L) printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
    
    

    假算法
    分析:贪心地删边后检查每个点的度即可,居然能过?

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e4+5;
    struct Edge{
        int u,v,next;
    }edges[MAXN<<2];
    int head[MAXN],tot;
    int deg[MAXN];
    
    void init()
    {
        memset(head,-1,sizeof(head));
        tot =0 ;
        memset(deg,0,sizeof(deg));
    }
    
    void AddEdge(int u,int v)
    {
        edges[tot] = (Edge){u,v,head[u]};
        head[u] = tot++;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int cas = 1;
        int N,M,K,u,v;
        while(scanf("%d %d %d",&N,&M,&K)==3){
            init();
            memset(deg,0,sizeof(deg));
            int L,R; scanf("%d %d",&L, &R);
    
            for(int i=1;i<=K;++i){
                scanf("%d %d",&u,&v);
                v+=N;
                AddEdge(u,v);
                deg[u]++;  deg[v]++;
            }
    
            for(int e=0;e<tot;++e){
                u = edges[e].u, v =edges[e].v;
                if(deg[u]>R || deg[v]>R){
                    deg[u]--;
                    deg[v]--;
                }
            }
    
            bool flag = true;
    
            for(int i=1;i<=N+M;++i){
                if(deg[i]<L || deg[i]>R){
                    flag = false;
                    break;
                }
            }
            printf("Case %d: ",cas++);
            if(flag) printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
    
    
    为了更好的明天
  • 相关阅读:
    node的function函数和路由代码的小例子
    关于node回调函数中同步和异步操作的理解
    node初学
    CTF知识点总结(二)
    知识图谱
    论文笔记 无监督与混合IDS
    CTF知识点总结(一)
    论文笔记 网络安全图谱以及溯源算法
    攻防世界 wtf.sh-150
    攻防世界 Web_php_wrong_nginx_config
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9610142.html
Copyright © 2011-2022 走看看