http://poj.org/problem?id=2762

强连通求子图和子图关系 + 子图关系是链式结构

 #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long const double eps=1e-;
const ll inf=1e9;
const ll mod=1e9+;
const int maxn=1e3+; struct node
{
int d;
node *to;
}*e[maxn]; bool vis[maxn]; int num,cnt_st,st[maxn],dfn[maxn],low[maxn],cnt_group,group[maxn],cnt_single,gx[maxn],gy[maxn];
bool vis_st[maxn],ifok; void tarjan(int d)
{
dfn[d]=low[d]=++num;
vis[d]=;
st[++cnt_st]=d;
node *p=e[d];
while (p)
{
if (!vis[p->d])
{
tarjan(p->d);
low[d]=min(low[d],low[p->d]);
}
else if (!vis_st[p->d])
low[d]=min(low[d],dfn[p->d]);
p=p->to;
}
if (dfn[d]==low[d])
{
cnt_group++;
while (d!=st[cnt_st])
{
group[st[cnt_st]]=cnt_group;
vis_st[st[cnt_st]]=;
cnt_st--;
}
group[st[cnt_st]]=cnt_group;
vis_st[st[cnt_st]]=;
cnt_st--;
}
} int main()
{
node *p;
int T,n,m,x,y,i;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
for (i=;i<=n;i++)
e[i]=NULL; while (m--)
{
scanf("%d%d",&x,&y);
p=new node();
p->d=y;
p->to=e[x];
e[x]=p;
} memset(vis,,sizeof(vis));
memset(vis_st,,sizeof(vis_st));
num=,cnt_st=,cnt_group=;
for (i=;i<=n;i++)
if (!vis[i])
tarjan(i); /*
if all are ok:需要的是链式结构
1.对于一个子图,最多只有一个子图指向它,最多只有一个子图被它指向(非头结点)
2.有且只有一个子图,没有子图指向它(头结点)
*/ ifok=,cnt_single=;
memset(gx,,sizeof(gx));
memset(gy,,sizeof(gy));
for (i=;i<=n;i++)
{
p=e[i];
while (p)
{
///i -> p->d
if (group[p->d]!=group[i])
{
if (gx[group[p->d]]==)
gx[group[p->d]]=group[i];
else if (gx[group[p->d]]!=group[i])
ifok=; if (gy[group[i]]==)
gy[group[i]]=group[p->d];
else if (gy[group[i]]!=group[p->d])
ifok=;
}
p=p->to;
}
}
for (i=;i<=cnt_group;i++)
if (!gx[i])
cnt_single++; printf("%s\n",(ifok&(cnt_single==))?"Yes":"No");
}
return ;
}
/*
10
3 2
1 2
3 2 4 3
1 2
2 3
3 1 3 3
1 2
2 3
3 1 5 4
1 2
2 3
3 4
4 5 3 2
1 2
1 3 3 2
1 2
3 2 4 3
1 2
2 3
3 1 3 3
1 2
2 3
3 1 5 4
1 2
2 3
3 4
4 5 3 2
1 2
1 3
*/

Advance:如何判断两个结点是否属于同一个单向连通子图(就是是否可以从x到y或者从y到x)[多组数据]

强连通图,同一个集合内的点,可以互相到达

拓扑结构,point a in group x, point b in group y,如x能到达y,则a能到b,但b不能到a。

其它情况下,两者均不能到达对方。

在拓扑结构中,一个点也许有多个孩子,多个祖先。

没有想到什么好的方法。。。不过感觉应该有。

TLE代码

 #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
//#include <map> const double eps=1e-;
const ll inf=1e9;
const ll mod=1e9+;
const int maxn=1e3+; struct node
{
int d;
node *to;
}*e[maxn]; bool vis[maxn],f[maxn][maxn];
int c,q[maxn]; //void dfs(int d)
//{
// vis[d]=1;
// f[c][d]=1;
// node *p=e[d];
// while (p)
// {
// if (!vis[p->d])
// dfs(p->d);
// p=p->to;
// }
//} //map<int,int> ma; int main()
{
node *p;
int T,n,m,x,y,i,j;
int head,tail,d;
int num;
bool v;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
for (i=;i<=n;i++)
e[i]=;
// ma.clear();
num=;
while (m--)
{
scanf("%d%d",&x,&y);
// if (ma.find(x)!=ma.end())
// x=ma[x];
// else
// ma[x]=++num,x=num;
// if (ma.find(y)!=ma.end())
// y=ma[y];
// else
// ma[y]=++num,y=num; p=new node();
p->d=y;
p->to=e[x];
e[x]=p;
}
for (c=;c<=n;c++)
{
// memset(vis,0,sizeof(vis));
// dfs(c); q[]=c;
vis[c]=;
head=,tail=;
while (head<tail)
{
head++;
d=q[head];
p=e[d];
while (p)
{
if (!vis[p->d])
{
vis[p->d]=;
q[++tail]=p->d;
f[c][p->d]=;
}
p=p->to;
}
}
for (j=;j<=tail;j++)
vis[q[j]]=;
} v=;
for (i=;i<=n;i++)
for (j=i+;j<=n;j++)
if (!f[i][j] && !f[j][i])
v=;
printf("%s\n",v?"Yes":"No");
}
return ;
}

单向连通图 Going from u to v or from v to u? poj2762的更多相关文章

  1. poj2767,单向连通图判定,缩点+重新建图+新图DFS

    /*该题被博客里标记为中等题,30分钟内1A,掌握了算法就简单了,单向连通图判定,单向连通图缩点 后必然唯一存在出度为0的点和入度为0的点,并且从入度为0的点出发,可以遍历所有点后到达出度为0点 (一 ...

  2. POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)

    这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径. 方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变 ...

  3. 判断单向连通图(拓扑排序+tarjan缩点)

    题意: 给你一个有向图,如果对于图中的任意一对点u和v都有一条从u到v的路或从v到u的路,那么就输出’Yes’,否则输出’No’. 理解:当出现两个及以上入度为0的点(有一个就可能是别人到它,有两个的 ...

  4. POJ2762 单向连通图(缩点+拓扑排序

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19552 ...

  5. [强连通分量] 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 ...

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

    题目描述:为了让他们的儿子变得更勇敢些,Jiajia和Wind将他们带到一个大洞穴中.洞穴中有n个房间,有一些单向的通道连接某些房间.每次,Wind选择两个房间x和y,要求他们的一个儿子从一个房间走到 ...

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

    题目链接:http://poj.org/problem?id=2762 题意是 有t组样例,n个点m条有向边,取任意两个点u和v,问u能不能到v 或者v能不能到u,要是可以就输出Yes,否则输出No. ...

  8. POJ 2762 Going from u to v or from v to u?(强联通 + TopSort)

    题目大意: 为了锻炼自己的儿子 Jiajia 和Wind 把自己的儿子带入到一个洞穴内,洞穴有n个房间,洞穴的道路是单向的. 每一次Wind 选择两个房间  x 和 y,   让他的儿子从一个房间走到 ...

  9. poj2762 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: 13040 ...

  10. poj 2762 Going from u to v or from v to u? (推断它是否是一个薄弱环节图)

    意甲冠军:给定一个有向图有m单向边缘.免费推断是否两点起来(a可以b要么b可以a或最多彼此),该请求 弱联通重量. 算法: 缩点求强连通分量.然后又一次建图.推断新图是否是一条单链,即不能分叉,假设分 ...

随机推荐

  1. C# 关于获取周,月,年时间大全

    DateTime now = DateTime.Now; DayOfWeek dayOfWeek = now.DayOfWeek; : (int)dayOfWeek; //本周第一天(此结果是周一,如 ...

  2. Laravel5.5添加新路由文件并制定规则

    Laravel5.5里面有4个默认的路由文件,其中web.php是默认路由文件,如果需要添加其他路由文件,按照以下步骤进行. 此处以添加网站home前端路由举例,我已经先在/app/Http/Cont ...

  3. set,get方法(属性,索引器)

    很多时候我们不可以把一些字段暴露出来允许别人调用和修改,为了隐藏这些字段又便于加限制的使用,在面向对象编程中一般采用写get set函数的办法,比如: //字段_age, "_"表 ...

  4. 设置ll命令

    ll 是 ls -l的别名,之所以 ll出现错误是因为没有定义别名. 如果要实现ll 命令,可以做如下操作: 1.编辑 ~./bashrc 添加 ls -l 的别名为 ll即可. vi /root/. ...

  5. vue 表单校验报错 "Error: please transfer a valid prop path to form item!"

    vue 表单校验报错 "Error: please transfer a valid prop path to form item!" 原因:prop的内容和rules中定义的名称 ...

  6. git——commit成功后,GitHub方格不变绿

    一通百度该设置的都设置了,还是不好使 发现有提示一栏 pull request的东西  在网上查貌似是因为两个分支内容不同 提示是否合并,还查到了不变绿可能的原因. Contributions未被Gi ...

  7. tarjan求强连通+缩点——cf1248E

    这题好像是DEF里最水的,, /* 建图:如果a认识b,那么从a->b连一条边,将点分成两个集合A,B,没有从A->B的边 求出强连通分量,再造一张新图,新图中任取一个的出度为0的点作为集 ...

  8. 【前端技术】一篇文章搞掂:CSS

    Flex布局 Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性. /*父容器,设置弹性布局*/ .parent{display: flex;} /*设置父容器主轴方向* ...

  9. STM32嵌入式开发学习笔记(一)

    本文中,笔者将介绍使用嵌入式开发工具Keil uVision5,使用C语言,对微处理器STM32F103C8进行嵌入式开发. 开发使用C语言,首先需要新建一个C语言文件,将其设为主函数的入口,因此,将 ...

  10. linux R环境安装以及注意事项

    安装Ryum install Ryum install readline-develyum install libXt-devel 1.安装后在R命令行启动Rserve,在脚本中不要重复加载Rserv ...