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;
}