poj 2553 The Bottom of a Graph【强连通分量求汇点个数】
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 9641 | Accepted: 4008 |
Description
Let n be a positive integer, and let p=(e1,...,en) be a sequence of length n of edges ei∈E such that ei=(vi,vi+1) for a sequence of vertices (v1,...,vn+1). Then p is called a path from vertex v1 to vertex vn+1 in Gand we say that vn+1 is reachable from v1, writing (v1→vn+1).
Here are some new definitions. A node v in a graph G=(V,E) is called a sink, if for every node w in G that is reachable from v, v is also reachable from w. The bottom of a graph is the subset of all nodes that are sinks, i.e., bottom(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}. You have to calculate the bottom of certain graphs.
Input
Output
Sample Input
3 3
1 3 2 3 3 1
2 1
1 2
0
Sample Output
1 3
2
定义:点v是汇点须满足 --- 对图中任意点u,若v可以到达u则必有u到v的路径;若v不可以到达u,则u到v的路径可有可无。
题意:在n个点m条边的有向图里面,问有多少个点是汇点。
分析:首先若SCC里面有一个点不是汇点,那么它们全不是汇点,反之也如此。这也就意味着一个SCC里面的点要么全是,要么全不是。在求出SCC并缩点后,任一个编号为A的SCC若存在指向编号为B的SCC的边,那么它里面所有点必不是汇点(因为编号为B的SCC不可能存在指向编号为A的SCC的边)。若编号为A的SCC没有到达其他SCC的路径,那么该SCC里面所有点必是汇点。因此判断的关键在于SCC的出度是否为0.
思路:先用tarjan求出所有SCC,然后缩点后找出所有出度为0的SCC,并用数字存储点,升序排列后输出。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
#include<algorithm>
#define MAX 21000
#define INF 0x3f3f3f
using namespace std;
int cost[MAX];
int low[MAX],dfn[MAX];
int head[MAX],instack[MAX];
int ans,n,m;
int sccno[MAX],clock;//sccno用来记录当前点属于哪个scc,
int scccnt;//记录总共有多少个scc
stack<int>s;
vector<int>newmap[MAX];//scc缩点之后储存新图
vector<int>scc[MAX];//用来记录scc中的点
int out[MAX];//记录scc的入度
int ant[MAX];
struct node
{
int beg,end,next;
}edge[MAX];
void init()
{
memset(head,-1,sizeof(head));
ans=0;
}
void add(int u,int v)
{
edge[ans].beg=u;
edge[ans].end=v;
edge[ans].next=head[u];
head[u]=ans++;
}
void getmap()
{
int i,j,a,b;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
}
}
void tarjan(int u)
{
int v,i,j;
low[u]=dfn[u]=++clock;
s.push(u);
instack[u]=1;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].end;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
scccnt++;
scc[scccnt].clear();//??
while(1)
{
v=s.top();
s.pop();
instack[v]=0;
sccno[v]=scccnt;
scc[scccnt].push_back(v);
if(v==u)
break;
}
}
}
void find(int l,int r)
{
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(sccno,0,sizeof(sccno));
memset(instack,0,sizeof(instack));
clock=scccnt=0;
for(int i=l;i<=r;i++)
{
if(!dfn[i])
tarjan(i);
}
}
void suodian()
{
int i,j;
for(i=1;i<=scccnt;i++)
{
newmap[i].clear();
out[i]=0;
}
for(i=0;i<ans;i++)//遍历所有的边
{
int u=sccno[edge[i].beg];//当前边的起点
int v=sccno[edge[i].end];//当前边的终点
if(u!=v)//因为sccno中记录的是当前点属于哪个scc,所以u!=v证明不在同一个scc但是由一条边相连,
{ //证明这两个scc联通
newmap[u].push_back(v);//将scc中的点储存下来 ??
out[u]++;//两个scc联通 则入度加一,
}
}
}
void solve()
{
int i,j,k=0;
for(i=1;i<=scccnt;i++)
{
if(out[i]==0)
{
for(j=0;j<scc[i].size();j++)
ant[k++]=scc[i][j];
}
}
sort(ant,ant+k);
for(i=0;i<k;i++)
{
if(i<k-1)
printf("%d ",ant[i]);
else
printf("%d",ant[i]);
}
printf("\n");
}
int main()
{
int j,i;
while(scanf("%d",&n),n)
{
scanf("%d",&m); init();
getmap();
find(1,n);
suodian();
solve();
}
return 0;
}
poj 2553 The Bottom of a Graph【强连通分量求汇点个数】的更多相关文章
- poj 2553 The Bottom of a Graph(强连通分量+缩点)
题目地址:http://poj.org/problem?id=2553 The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K ...
- POJ 2553 The Bottom of a Graph (强连通分量)
题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假 ...
- poj - 2186 Popular Cows && poj - 2553 The Bottom of a Graph (强连通)
http://poj.org/problem?id=2186 给定n头牛,m个关系,每个关系a,b表示a认为b是受欢迎的,但是不代表b认为a是受欢迎的,关系之间还有传递性,假如a->b,b-&g ...
- POJ 2553 The Bottom of a Graph(强连通分量)
POJ 2553 The Bottom of a Graph 题目链接 题意:给定一个有向图,求出度为0的强连通分量 思路:缩点搞就可以 代码: #include <cstdio> #in ...
- [poj 2553]The Bottom of a Graph[Tarjan强连通分量]
题意: 求出度为0的强连通分量. 思路: 缩点 具体有两种实现: 1.遍历所有边, 边的两端点不在同一强连通分量的话, 将出发点所在强连通分量出度+1. #include <cstdio> ...
- POJ 2553 The Bottom of a Graph(强连通分量的出度)
题意: 求出图中所有汇点 定义:点v是汇点须满足 --- 对图中任意点u,若v可以到达u则必有u到v的路径:若v不可以到达u,则u到v的路径可有可无. 模板:http://www.cnblogs.co ...
- POJ 2553 The Bottom of a Graph (Tarjan)
The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 11981 Accepted: ...
- POJ 2553 The Bottom of a Graph Tarjan找环缩点(题解解释输入)
Description We will use the following (standard) definitions from graph theory. Let V be a nonempty ...
- poj 2553 The Bottom of a Graph
求解的是有向图中满足“自己可达的顶点都能到达自己”的顶点个数如果强连通分量中某个顶点,还能到达分量外的顶点,则该连通分量不满足要求// 因此,本题要求的是将强连通分量缩点后所构造的新图中出度为0的顶点 ...
随机推荐
- Google Web Designer 测试
这东东完全就是一个flash啊,简单测试,感觉就是个做HTML5动画的..不过暂时是beta版的, 官方安装版的半天打不开,这边有个绿色版的,需要的童鞋可以这里下载:百度网盘
- onbeforeunload、beforeunload
<script type="text/javascript"> function addOnBeforeUnload(e) { var ev = e || ev ...
- C# 翻页设计:首页,上一页,下一页,末页 ,跳转
int pageSize = 0; //每页显示行数 int nMax = 0; //总记录数 int pageCount = 0; //页数=总记录数/每页显示行数 int pageCurrent ...
- sql server 与C#数据类型对应表
- 用powerdesigner建模工具生成数据库
1,使用powerdesignerP:主键 F:外键 M:是否可为空 2,两张表建立主外键关系时,主外键名称要相同.比如A表 A_id name 说明id(P) B表 B_id name 说明id ...
- slivelight5和数据库交互
最近开始研究sliverlight和数据库交互了,无奈网上资料较少,查阅了大量资料终于成功了,但是我记得还有别的方法,希望大家讨论一下 数据访问层我的用的是ado.net实体数据模型 然后新建了一个w ...
- php的ftp类
1.需求 了解php的ftp使用 2.例子 使用CI封装好的ftp类库 上传 $this->load->library('ftp'); $config['hostname'] = 'ftp ...
- ios:如何将自己编写的软件放到真正的iPhone上运行(转)
想要将自己编写的软件放到真正的iPhone上去运行,首先你需要成为Apple Developer计划的成员.其次,你需要设置程序ID和认证书,在这之后你就可以在你指定的iPhone上运行你的程序了.下 ...
- scanf格式控制符
格式控制 . %d %o %x %c %s %f %e 无%u格式.%g格式 . scanf("%3d%3d", &a, &b); 输入: //a=123,b=45 ...
- Docker日志自动化: ElasticSearch、Logstash、Kibana以及Logspout
http://www.open-open.com/lib/view/open1432107136989.html