zoukankan      html  css  js  c++  java
  • 【离散化】【DFS】Gym

    题意:给你一张有向图,每条边有个限制范围,只有权值在限制范围内的人能走这条边,问你权值不超过K的人中,有多少人能从S到T。

    K很大,因此我们只处理边的范围的上下界这O(m)个权值能否到达,以防万一,还处理了这些权值+1、-1的可达性。然后去重。离散化出来的这些区间中,两个端点都可达的话,其内部的点也必然可达。当然端点本身也是可达的。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    using namespace std;
    set<int>S;
    bool cant[5005],vis[1005];
    int first[1005],nex[5005],v[5005],w1[5005],w2[5005],e;
    void AddEdge(int U,int V,int W1,int W2){
        v[++e]=V;
        w1[e]=W1;
        w2[e]=W2;
        nex[e]=first[U];
        first[U]=e;
    }
    int n,m,K,Sta,End,b[30005],q;
    bool c[30005];
    void dfs(int U){
        vis[U]=1;
        for(int i=first[U];i;i=nex[i]){
            if(!cant[i] && !vis[v[i]]){
                dfs(v[i]);
            }
        }
    }
    void Insert(int x){
        if(S.find(x)==S.end()){
            b[++q]=x;
            S.insert(x);
        }
    }
    int main(){
        int x,y,z1,z2;
        //freopen("h.in","r",stdin);
        scanf("%d%d%d%d%d",&n,&m,&K,&Sta,&End);
        for(int i=1;i<=m;++i){
            scanf("%d%d%d%d",&x,&y,&z1,&z2);
            AddEdge(x,y,z1,z2);
            if(z1!=1){
                Insert(z1-1);
            }
            Insert(z1);
            if(z1!=K){
                Insert(z1+1);
            }
    
            if(z2!=1){
                Insert(z2-1);
            }
            Insert(z2);
            if(z1!=K){
                Insert(z2+1);
            }
        }
        sort(b+1,b+q+1);
        /*for(int i=1;i<=q;++i){
            printf("%d ",b[i]);
        }
        puts("");*/
        int ans=0;
        for(int i=1;i<=q;++i){
            memset(cant,0,sizeof(cant));
            for(int j=1;j<=e;++j){
                if(b[i]<w1[j] || b[i]>w2[j]){
                    cant[j]=1;
                }
            }
            memset(vis,0,sizeof(vis));
            dfs(Sta);
            if(vis[End]){
                c[i]=1;
                ++ans;
            }
        }
        /*for(int i=1;i<=q;++i){
            if(c[i]){
                printf("%d ",b[i]);
            }
        }
        puts("");*/
        for(int i=1;i<q;++i){
            if(c[i] && c[i+1]){
                ans+=(b[i+1]-b[i]-1);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    LeetCode刷题记录
    开始学习Functional Programming
    明天软软onsite
    Criteo电面二
    Jet.com
    还需要补充很多知识
    重新粗推了一下Master Theorem
    买了第一台mac
    病来如山倒
    Integer.parseInt vs Integer.valueOf
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7881895.html
Copyright © 2011-2022 走看看