[Luo Gu P4436] HNOI / AHOI2018 game

Problem Description

A small G and H in the geocaching small, there are n rooms in a row, numbered 1,2, ..., n, has a door between adjacent rooms. Part of the door unlocked (thus the need for a corresponding keys to open the door), the rest of the door can be opened directly. Now tell a little small G H key to every lock in which room (each lock and only a key corresponding) and instructions to p times: The first time i make a small H from \ (S_i \) rooms starting to \ (T_i \) a room. But the small G sometimes deliberately placed in command of a dead end, and the small H not want to waste the extra strength to try, so would like to investigate in advance whether there will be clear instructions every time a path.

Are you able to answer it as a small H?

Input Format

The first line of three numbers: n, m, p, n representatives room, m the locked door, and the p interrogation. Next m lines of two numbers x, y representative of X 1 to x + y of the key in the room. Next p rows, where i is the row of two integers \ (S_i, T_i \) , on behalf of a request.

Output Format

P output lines, each line a "YES" or "NO", or represent can not reach.

Sample input

5 4 5
1 3
2 2
3 1
4 4
2 5
3 5
4 5
2 1
3 1

Sample Output

YES
NO
YES
YES
NO

Explanation

Resolve

It can be found for each point i, the last to reach the region must be some interval [Li, Ri]. The question then is how to find these intervals.

If a door key on the left side of the door, then do not pass through from the right side of the door; if this door on the right, do not go through from the left. So, if we are on both sides of each door, even by a not reach to reach the edge, can be found in a range interval must at this point may be a point in front of the point sequence obtained from the topology (only the front side there is connected to the point this point). So, you can use topological sorting, the first point for the team, left to right extended, expanded the number of points equal attention to the door number to the right of the door minus one, see specific code.

However, a possible interaction of the range, there may be connected into a ring, so that topological sort does not make sense. Therefore, the beginning require pretreatment of the cross section is possible, and shrunk to a point of this range. While all the information is updated to point after reduction.

Response to a query, you can simply determine whether the T in the range of up to S's.

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define N 1000002
#define M 1000002
using namespace std;
int head[N],ver[M],nxt[M],d[N],t;
int n,m,q,i,x[N],y[N],pos[N],cnt=1,gap[N],l[N],r[N];
bool lock[N];
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
void insert(int x,int y)
{
    t++;
    ver[t]=y;
    nxt[t]=head[x];
    head[x]=t;
    d[y]++;
}
bool check(int x,int y)
{
    if(y==0||y==cnt+1) return 0;
    if(x<y) y--;
    return l[x]<=pos[y]&&pos[y]<=r[x];//钥匙是否在当前可达区间中
}
void toposort()
{
    queue<int> q;
    for(int i=1;i<=cnt;i++){
        if(d[i]==0) q.push(i);
    }
    while(!q.empty()){
        int x=q.front();
        q.pop();
        bool flag=1;
        while(flag){
            flag=0;
            while(check(x,l[x]-1)) l[x]=l[l[x]-1],flag=1;//可以就更新为左边的左端点
            while(check(x,r[x]+1)) r[x]=r[r[x]+1],flag=1;//更新为右边的右端点
        }
        for(int i=head[x];i;i=nxt[i]){
            int y=ver[i];
            d[y]--;
            if(d[y]==0) q.push(y);
        }
    }
}
int main()
{
    n=read();m=read();q=read();
    for(i=1;i<=m;i++){
        x[i]=read();y[i]=read();
        lock[x[i]]=1;
    }
    lock[n]=1;
    for(i=1;i<=n;i++){
        gap[i]=cnt;
        if(lock[i]){
            l[cnt]=r[cnt]=cnt;
            cnt++;
        }
    }
    cnt--;
    for(i=1;i<=m;i++){
        int tx=gap[x[i]],ty=gap[y[i]];
        pos[tx]=ty;
        if(ty<=tx) insert(tx+1,tx);
        else insert(tx,tx+1);
    }
    toposort();
    for(i=1;i<=q;i++){
        int x=read(),y=read();
        x=gap[x],y=gap[y];
        if(l[x]<=y&&y<=r[x]) puts("YES");
        else puts("NO");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11669096.html