H - Security Badges ( 区间离散化 )

H - Security Badges ( 区间离散化 )

Gym - 101617H 

题意:给出n个房间和m扇门,共有k个人编号1~k,每扇门可以从Ai到Bi,并且编号为 Li ~ Ri 的人都可以通过,给出S、T,问有多少人可以从S到T。

(2 ≤ n ≤ 1,000; 1 ≤ m ≤ 5,000; 1 ≤ k ≤ 1e9 )       ( 1 ≤ s, t ≤ n; s != t)           (1 ≤ ai , bi ≤ n; 1 ≤ ci ≤ di ≤ k; ai != bi)

思路:直接考虑区间合并显然不太容易,所以需要区间离散化,把所有区间化成一个一个的小区间。最后的答案区间一定是由这些小区间组合而成。然后我们 dfs 检查每一个小区间是否可行。

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn = 2e4+10;
int b[maxn],cnt;
struct node {
    int l,r;
};
node a[1002][1002];
int via[1002],vis[maxn];
vector<int> G[1002];
int n,m,k,s,d,ans;

int dfs( int u, int L, int R )
{
    if ( u==d ) return 1;
    via[u] = 1;
    if ( u==d ) return 1;
    int sum = 0;
    for ( int i=0; i<G[u].size(); i++ ) {
        int v = G[u][i];
        if ( via[v]==1 ) continue ;
        if ( L>=a[u][v].l && R<=a[u][v].r ) sum += dfs(v,L,R);
    }
    return sum;
}

int main()
{
    cin>>n>>m>>k;
    cin>>s>>d;
    for ( int i=0; i<m; i++ ) {
        int u,v,l,r;scanf("%d %d %d %d",&u,&v,&l,&r);
        G[u].push_back(v);
        a[u][v] = {l,r};
        b[cnt++] = l; b[cnt++]=r;
    }
    sort(b,b+cnt);
    cnt = unique(b,b+cnt)-b;
    for ( int i=1; i<cnt; i++ ) {
        memset(via,0,sizeof(via));
        if ( dfs(s,b[i-1],b[i]) ) {
            ans += (b[i]-b[i-1]+1);
            if ( vis[i-1]==1 ) ans--;
            vis[i] = 1; vis[i-1] = 1;
        }
    }
    for ( int i=0; i<cnt; i++ ) {
        memset(via,0,sizeof(via));
        if ( vis[i]==0 && dfs(s,b[i],b[i]) ) ans++;
    }
    cout << ans << endl;

    return 0;
}

 

©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页