poj 2762 Going from u to v or from v to u?

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 17689   Accepted: 4745

Description

In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn‘t know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

Input

The first line contains a single integer T, the number of test cases. And followed T cases.

The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.

Output

The output should contain T lines. Write ‘Yes‘ if the cave has the property stated above, or ‘No‘ otherwise.

Sample Input

1
3 3
1 2
2 3
3 1

Sample Output

Yes

Source

POJ Monthly--2006.02.26,zgl & twb

题目大意

给出一些点,和他们之间的有向边,如果图中任意两点 x,y 之间满足 x 可以到达 y 或者 y 可以到达 x ,就输出“Yes”,否则输出“No”

因为n>1000 所以挨个判断是不可取的

所以我们用tarjan 求出强连通分量的个数

然后判断这几个强连通分量在不在一条链上就可以了

tarjan缩点+拓扑排序

屠龙宝刀点击就送

#include <cstring>
#include <ctype.h>
#include <cstdio>
#include <queue>
#define M 6005
#define N 1500
using namespace std;
void read(int &x)
{
    x=0;bool f=0;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘) f=1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
    x=f?(~x)+1:x;
}
int in[N],g[N][N],tim,dfn[N],col[N],sumcol,low[N],T,n,m,head[N],cnt,stack[N],top;
bool instack[N],vis[N];
struct node
{
    int next,to;
}edge[M];
void add(int u,int v)
{
    edge[++cnt].next=head[u];
    edge[cnt].to=v;
    head[u]=cnt;
}
int min(int a,int b)
{
    return a>b?b:a;
}
void dfs(int x)
{
    stack[++top]=x;
    instack[x]=1;
    vis[x]=1;
    low[x]=dfn[x]=++tim;
    for(int i=head[x];i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(instack[v]) low[x]=min(low[x],dfn[v]);
        else if(!vis[v])
        {
            dfs(v);
            low[x]=min(low[x],low[v]);
        }
    }
    if(low[x]==dfn[x])
    {
        sumcol++;
        while(x!=stack[top])
        {
            instack[stack[top]]=0;
            col[stack[top--]]=sumcol;
        }
        instack[stack[top]]=0;
        col[stack[top--]]=sumcol;
    }
}
bool judge()
{
    queue<int>q;
    for(int i=1;i<=sumcol;i++)
    if(!in[i]) q.push(i);
    if(q.size()>1) return false;
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=1;i<=sumcol;i++)
        if(g[now][i])
        {
            in[i]--;
            if(!in[i]) q.push(i);
        }
        if(q.size()>1) return false;
    }
    return true;
}
int main()
{
    read(T);
    for(;T--;)
    {
        memset(head,0,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(vis,0,sizeof(vis));
        memset(instack,0,sizeof(instack));
        memset(col,0,sizeof(col));
        memset(low,0,sizeof(low));
        memset(in,0,sizeof(in));
        memset(g,0,sizeof(g));
        tim=0;top=0;sumcol=0;cnt=0;
        bool f=false;
        read(n);
        read(m);
        for(int x,y,i=1;i<=m;i++)
        {
            read(x);
            read(y);
            add(x,y);
        }
        for(int i=1;i<=n;i++)
        if(!vis[i]) dfs(i);
        if(sumcol==1) {printf("Yes\n");continue;}
        for(int i=1;i<=n;i++)
        {
            for(int j=head[i];j;j=edge[j].next)
            {
                int v=edge[j].to;
                if(i!=v&&col[i]!=col[v])
                {
                    g[col[i]][col[v]]=1;
                    in[col[v]]++;
                }
            }
        }
        if(judge()) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
时间: 2024-11-03 05:30:50

poj 2762 Going from u to v or from v to u?的相关文章

POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)

职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可能从一点到还有一点的. 代码例如以下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include

POJ 2762 Going from u to v or from v to u? (有向图求单连通性)

POJ 2762 Going from u to v or from v to u? 链接:http://poj.org/problem?id=2762 题意:为了让他们的儿子变得更勇敢些,Jiajia 和Wind 将他们带到一个大洞穴中.洞穴中有n 个房间,有一些单向的通道连接某些房间.每次,Wind 选择两个房间x 和y,要求他们的一个儿子从一个房间走到另一个房间,这个儿子可以从x 走到y,也可以从y 走到x.Wind 保证她布置的任务是可以完成的,但她确实不知道如何判断一个任务是否可以完成

POJ 2762 Going from u to v or from v to u? (判断弱连通)

http://poj.org/problem?id=2762 题意:给出有向图,判断任意两个点u和v,是否可以从u到v或者从v到u. 思路: 判断图是否是弱连通的. 首先来一遍强连通缩点,重新建立新图,接下来我们在新图中找入度为0的点,入度为0的点只能有1个,如果有多个那么这些个点肯定是不能相互到达的. 如果只有一个入度为0的点,走一遍dfs判断新图是否是单链,如果有分支,那么分支上的点肯定是不能相互到达的. 1 #include<iostream> 2 #include<algorit

[ tarjan + dfs ] poj 2762 Going from u to v or from v to u?

题目链接: http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14546   Accepted: 3837 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cav

poj 2762 Going from u to v or from v to u? (判断是否是弱联通图)

题意:给定一个有向图有m条单向边,判断是否任意两点都可达(a能到b或者b能到a或者互相可达),即求 弱联通分量. 算法: 先缩点求强连通分量.然后重新建图,判断新图是否是一条单链,即不能分叉,如果分叉了就会存在不可达的情况. 怎么判断是否是单链呢? 就是每次入度为0的点都只有一个,即每次队列里只有一个点. (    o(╯□╰)o.....好像已经是第二次用pair记录原图的点对,然后存pair的vector忘记清空导致wa来wa去! ) #include<cstdio> #include&l

POJ 2762 Going from u to v or from v to u?(强联通,拓扑排序)

http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14573   Accepted: 3849 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has

POJ 2762 Going from u to v or from v to u? (图论-tarjan)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14469   Accepted: 3801 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

[强连通分量] POJ 2762 Going from u to v or from v to u?

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17089   Accepted: 4590 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

poj 2762 Going from u to v or from v to u?【强连通分量缩点+拓扑排序】

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15812   Accepted: 4194 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

poj 2762 Going from u to v or from v to u? trajan+拓扑

Going from u to v or from v to u? Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of thei