Gym - 101652T Security Badge

Security Badge
题 意:有n个房间,m个门,k个员工,每个门有一个密码[ci,di]只有编号在这个范围类的员工才能通过这个门,k个员工每个员工都有一个唯一的编号。每个门由房间ai开向房间bi,密码为[ci,di]。题目保证不会有重边。输入s,t问有多少员工可以通过s,t。

数据范围:
1<=n<=1000
1<=m<=5000
1<=k<=1e9
1<=ai,bi<=n
1<=ci<=di<=k

输入样例:

4 5 10
3 2
1 2 4 7
3 1 1 6
3 4 7 10
2 4 3 5
4 2 8 9

输出样例:

5

思 路:能通过的区间,一定是ci,di的组合,那么就可以离散化,枚举可以通过的区间,算贡献。
收 获:这是一道好题,暴力枚举区间贡献。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e3+5;
struct node{
    int next;
    int l,r;
    int to;
};
node G[maxn];
int head[maxn];
int a[maxn<<1];
int total;
bool vis[maxn],flag;
int n,m,k;
int s,t;
void addEdge(int u,int v,int l,int r){
    G[total].to = v;
    G[total].l = l;
    G[total].r = r;
    G[total].next = head[u];
    head[u] = total++;
}
void init(){
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    total=0;
}
void dfs(int s1,int l,int r){
    vis[s1] = true;
    if(s1 == t){
        flag = true;
        return;
    }
    for(int i=head[s1];i!=-1;i=G[i].next){
        int to = G[i].to;
        if(vis[to])continue;
        if(G[i].l<=l  && G[i].r >=r) dfs(to,l,r);
    }
}
int main(){
    while(~scanf("%d %d %d",&n,&m,&k)){
        scanf("%d %d",&s,&t);
        init();
        int num = 0;
        int u,v,l,r;
        for(int i=0;i<m;i++){
            scanf("%d %d %d %d",&u,&v,&l,&r);
            a[num] = l;
            a[num+1] = r+1;   //必须左闭右开
            addEdge(u,v,l,r);
            num+=2;
        }
        sort(a,a+2*m);
        num = unique(a,a+2*m)-a;
        int sum = 0;
        for(int i=1;i<num;i++){
            memset(vis,false,sizeof(vis));
            flag = false;
            dfs(s,a[i-1],a[i]-1); //防止重复计算。
            if(flag){
                sum += a[i]-a[i-1];
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/81811612