zoukankan      html  css  js  c++  java
  • codeforces555E

    Case of Computer Network

     CodeForces - 555E 

    Andrewid the Android is a galaxy-known detective. Now he is preparing a defense against a possible attack by hackers on a major computer network.

    In this network are n vertices, some pairs of vertices are connected by m undirected channels. It is planned to transfer q important messages via this network, the i-th of which must be sent from vertex si to vertex di via one or more channels, perhaps through some intermediate vertices.

    To protect against attacks a special algorithm was developed. Unfortunately it can be applied only to the network containing directed channels. Therefore, as new channels can't be created, it was decided for each of the existing undirected channels to enable them to transmit data only in one of the two directions.

    Your task is to determine whether it is possible so to choose the direction for each channel so that each of the q messages could be successfully transmitted.

    Input

    The first line contains three integers nm and q (1 ≤ n, m, q ≤ 2·105) — the number of nodes, channels and important messages.

    Next m lines contain two integers each, vi and ui (1 ≤ vi, ui ≤ nvi ≠ ui), that means that between nodes vi and ui is a channel. Between a pair of nodes can exist more than one channel.

    Next q lines contain two integers si and di (1 ≤ si, di ≤ nsi ≠ di) — the numbers of the nodes of the source and destination of the corresponding message.

    It is not guaranteed that in it initially possible to transmit all the messages.

    Output

    If a solution exists, print on a single line "Yes" (without the quotes). Otherwise, print "No" (without the quotes).

    Examples

    Input
    4 4 2
    1 2
    1 3
    2 3
    3 4
    1 3
    4 2
    Output
    Yes
    Input
    3 2 2
    1 2
    3 2
    1 3
    2 1
    Output
    No
    Input
    3 3 2
    1 2
    1 2
    3 2
    1 3
    2 1
    Output
    Yes

    Note

    In the first sample test you can assign directions, for example, as follows: 1 → 2, 1 → 3, 3 → 2, 4 → 3. Then the path for for the first message will be 1 → 3, and for the second one — 4 → 3 → 2.

    In the third sample test you can assign directions, for example, as follows: 1 → 2, 2 → 1, 2 → 3. Then the path for the first message will be 1 → 2 → 3, and for the second one — 2 → 1.

    简要题意:给出一个无向图,给出q个询问S,T表示从S走到T。
    问能否给这张图的边定向,使得满足q个询问

    sol:因为是无向图,所以在同一个强联通分量中是两两可以随意到达,然后可以搞成一棵树,树上可以差分一下,两个数组p0,p1,S位置p0++,T位置p1++,Lca处p0--,p1--,看看是否有一个点既有p0又有p1就No了

    /*
    ¼òÒªÌâÒ⣺¸ø³öÒ»¸öÎÞÏòͼ£¬¸ø³öq¸öѯÎÊS£¬T±íʾ´ÓS×ßµ½T¡£
    ÎÊÄÜ·ñ¸øÕâÕÅͼµÄ±ß¶¨Ïò£¬Ê¹µÃÂú×ãq¸öѯÎÊ
    */
    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0; bool f=0; char ch=' ';
        while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
        while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0) {putchar('-'); x=-x;}
        if(x<10) {putchar(x+'0'); return;}
        write(x/10); putchar((x%10)+'0');
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=200005,M=400005;
    int n,m,Q;
    int tot=0,Next[M],to[M],head[N];
    struct Ques{int S,T;}qq[N];
    inline void Link(int x,int y)
    {
        Next[++tot]=head[x]; to[tot]=y; head[x]=tot;
    }
    int cnt=0,dfn[N],low[N],top=0,Sta[N],now=0,Bel[N];
    bool ins[N];
    inline void tarjan(int x,int fat)
    {
        int i;
        bool bo=1;
        dfn[x]=low[x]=++cnt; Sta[++top]=x; ins[x]=1;
        for(i=head[x];i;i=Next[i])
        {
            if(to[i]==fat&&bo) {bo=0; continue;}
            if(!dfn[to[i]])
            {
                tarjan(to[i],x); low[x]=min(low[x],low[to[i]]);
            }
            else if(ins[to[i]]) low[x]=min(low[x],dfn[to[i]]);
        }
        if(dfn[x]==low[x])
        {
            int oo=0; now++;
            while(oo!=x)
            {
                oo=Sta[top--]; Bel[oo]=now; ins[oo]=0;
            }
        }
    }
    vector<int>E[N];
    #define PB push_back
    int fa[N];
    inline int gf(int x)
    {
        return (fa[x]==x)?(x):(fa[x]=gf(fa[x]));
    }
    int Dep[N],ff[N][23];
    inline void dfs(int x,int fat)
    {
        int i;
        for(i=0;i<E[x].size();i++) if(E[x][i]!=fat)
        {
            Dep[E[x][i]]=Dep[x]+1; ff[E[x][i]][0]=x; dfs(E[x][i],x);
        }
    }
    inline int ask_lca(int x,int y)
    {
        int i;
        if(Dep[x]<Dep[y]) swap(x,y);
        for(i=19;~i;i--) if(Dep[ff[x][i]]>=Dep[y]) x=ff[x][i];
        if(x==y) return x;
        for(i=19;~i;i--) if(ff[x][i]!=ff[y][i]) x=ff[x][i],y=ff[y][i];
        return ff[x][0];
    }
    int path[N][2];
    bool Vis[N];
    inline void dfss(int x,int fat)
    {
        int i;
        Vis[x]=1;
        for(i=0;i<E[x].size();i++)
        {
            int V=E[x][i]; if(V==fat) continue;
            dfss(V,x);
            path[x][0]+=path[V][0]; path[x][1]+=path[V][1];
        }
    }
    int main()
    {
    //    freopen("codeforces555E.in","r",stdin);
        int i,j,x,y;
        R(n); R(m); R(Q);
        for(i=1;i<=m;i++)
        {
            R(x); R(y); Link(x,y); Link(y,x);
        }
        for(i=1;i<=Q;i++) {R(qq[i].S); R(qq[i].T);}
        for(i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0);
    //    cout<<"now="<<now<<endl;
    //    for(i=1;i<=n;i++) cout<<i<<' '<<Bel[i]<<endl;
    //    puts("");
        for(i=1;i<=now;i++) fa[i]=i;
        for(i=1;i<=n;i++)
        {
            for(j=head[i];j;j=Next[j])
            {
                int o1=gf(Bel[i]),o2=gf(Bel[to[j]]);
                if(o1==o2) continue;
                E[Bel[i]].PB(Bel[to[j]]); E[Bel[to[j]]].PB(Bel[i]); fa[o1]=o2;
            }
        }
        for(i=1;i<=now;i++) if(!Dep[i]) {Dep[i]=1; dfs(i,0);}
    //    for(i=1;i<=now;i++) cout<<i<<' '<<Dep[i]<<endl;
    //    puts("");
        for(i=1;i<=19;i++) for(j=1;j<=now;j++) ff[j][i]=ff[ff[j][i-1]][i-1];
    //    for(i=1;i<=now;i++) cout<<i<<' '<<ff[i][0]<<endl;
    //    puts("");
        for(i=1;i<=Q;i++)
        {
            int S=Bel[qq[i].S],T=Bel[qq[i].T];
    //        cout<<S<<' '<<gf(S)<<' '<<T<<' '<<gf(T)<<endl;
            if(gf(S)!=gf(T)) return puts("No"),0;
            int lca=ask_lca(S,T);
    //        cout<<S<<' '<<T<<' '<<"lca="<<lca<<endl;
            path[S][0]++; path[lca][0]--; path[T][1]++; path[lca][1]--;
        }
    //    puts("");
    //    for(i=1;i<=now;i++) cout<<i<<' '<<path[i][0]<<' '<<path[i][1]<<endl;
        for(i=1;i<=now;i++) if(!Vis[i]) dfss(i,0);
        for(i=1;i<=Q;i++)
        {
            int S=Bel[qq[i].S],T=Bel[qq[i].T]; if(S==T) continue;
            if((path[S][0]&&path[S][1])||(path[T][0]&&path[T][1])) return puts("No"),0;
        }
        puts("Yes");
        return 0;
    }
    /*
    Input
    4 4 2
    1 2
    1 3
    2 3
    3 4
    1 3
    4 2
    Output
    Yes
    
    Input
    3 2 2
    1 2
    3 2
    1 3
    2 1
    Output
    No
    
    Input
    3 3 2
    1 2
    1 2
    3 2
    1 3
    2 1
    Output
    Yes
    */
    View Code
  • 相关阅读:
    Echarts 实现中国地图并轮播指定的地区?
    Linux安装Zookeeper
    初遇携程apollo配置中心
    eclipse安装lombok
    依赖layui form模块 复选框tree插件(拓展可根据属性单选还是多选,数据反选)
    centos7环境下mysql5.7的安装与配置
    中文算数验证码(加减乘除)
    获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
    jdk自带的MD5进行数据的加密与解密
    MyBatis-plus 代码生成器
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/11203123.html
Copyright © 2011-2022 走看看