poj 2553 缩点+染色+出度
题目链接:https://vjudge.net/problem/POJ-2553
如果不会tarjan算法,推荐博客:https://blog.csdn.net/mengxiang000000/article/details/51672725
题意大意:第一行输入一个n(n==0时结束程序),和一个m分别代表点数和边数,接下来一行有2*m个数字,每两个数字u,v表示一条有向边,即u可以到达v。
假如一个点a可以到b,c,d,e这些点,并且这些点也可以到达a点,则a点就是符合要求的点,即一个点可以到达的其他所有点都可以反过来到达这个点,则这个点就是符合要求的点,当然,如果这个点不能到其他任何点,那么这个点也是符合要求的,,现在就让我们找出所有符合要求的点,并且升序输出。。
所以我们的思路先用tarjan算法进行缩点操作,求出所有的强连通分量并且染色,这样的话一个强连通分量里所有的点之间都是相互可达的,而如果某个强连通分量里的点可以到其他强连通分量里的点,即这个强连通分量缩成一个点之后的出度不为0,那么这个强连通分量里所有的点都是不符合要求的,因为另一个强连通分量里的所有点必然不可能到达第一个强连通分量,否则两个强连通分量就可以合成一个了。所以我们的任务就是找到出度为0的所有强连通分量,然后把这些强连通分量里的点排序输出。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
#define eps 1e-8
#define ll long long
#define INF 0x3f3f3f3f
#define maxn 5005
/*struct point{
int u,w;
};
bool operator <(const point &s1,const point &s2)
{
if(s1.w!=s2.w)
return s1.w>s2.w;
else
return s1.u>s2.u;
}*/
int n,k,m,t;
int ans,top,cnt,color_num,time;
int dfn[maxn],vis[maxn],s[maxn],color[maxn],head[maxn],low[maxn];
//dfn[i]表示是第几个单位时间到i点,vis[i]表示i点是否在栈中,s是栈,color[i]表示点i的颜色,即它是属于哪个强连通分量
//low[i]用来判断强连通分量(low[i]==dfn[i])
int out[maxn],ss[maxn];//out[i]表示编号为i的强连通分量的出度,ss里面储存出度为0的强连通分量里面的点,
//之后把ss数组 里面的点排序之后输出
struct node{
int v,next;
}edge[maxn*];
void init()
{
memset(vis,,sizeof(vis));
memset(head,-,sizeof(head));
memset(color,,sizeof(color));
memset(out,,sizeof(out));
memset(dfn,,sizeof(dfn));
ans=top=cnt=color_num=time=;
}
void add(int u,int v)
{
edge[++cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt;
}
void tarjan(int u)//找强连通分量
{
dfn[u]=low[u]=++time;
vis[u]=;
s[++top]=u;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
if(!dfn[v])//第一次到v点,则继续深搜
tarjan(v);
low[u]=min(low[u],low[v]);//将最小值向上传递
}
if(low[u]==dfn[u])
{
ans++;
color_num++;
int v;
do{
v=s[top--];//出栈
vis[v]=;
color[v]=color_num;//染色,同一个强连通分量的所有点都是同一个编号
}while(u!=v);
}
}
void solve()
{
for(int i=;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int u=;u<=n;u++)//枚举所有点
{
for(int i=head[u];i!=-;i=edge[i].next)//枚举所有和u点相邻的边
{
int v=edge[i].v;
int a=color[u];
int b=color[v];
if(a!=b)//如果u和v的颜色不同,即a,b不同,则out[a]的出度++
{
out[a]++;
}
}
}
int num=;
for(int i=;i<=n;i++)
{
if(out[color[i]]==)//储存出度为0的强连通分量里面的点
ss[num++]=i;
}
sort(ss,ss+num);//排序
for(int i=;i<num;i++)//输出结果
{
if(i!=num-)
cout<<ss[i]<<' ';
else
cout<<ss[i]<<endl;
}
}
int main()
{
while((cin>>n>>m)&&n)
{
init();
for(int i=;i<m;i++)
{
int u,v;
cin>>u>>v;
add(u,v);
}
solve();
}
return ;
}
poj 2553 缩点+染色+出度的更多相关文章
- 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 Tarjan找环缩点(题解解释输入)
Description We will use the following (standard) definitions from graph theory. Let V be a nonempty ...
- 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 (强连通分量)
题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假 ...
- poj2186tarjan算法缩点求出度
poj2186tarjan算法缩点求出度 自己打一遍第一题,入门啦,入门啦 题目还算简单,多头牛,给你仰慕关系(可传递),问你最后有没有牛被所有的牛仰慕 根据关系可以建图,利用tarjan算法缩点处理 ...
- 缩点+染色+DFS codeforce467D
题目链接:https://vjudge.net/contest/219056#problem/A 推荐博客:https://blog.csdn.net/ck_boss/article/details/ ...
- poj 2553 强连通分支与缩点
思路:将所有强连通分支找出来,并进行缩点,然后找其中所有出度为0的连通分支,就是题目要求的. #include<iostream> #include<cstdio> #incl ...
- POJ 1236 Network Of Schools (强连通分量缩点求出度为0的和入度为0的分量个数)
Network of Schools A number of schools are connected to a computer network. Agreements have been dev ...
- poj 2553强连通+缩点
/*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v. 解;求强连通+缩点.求所有出度为0的点即 ...
随机推荐
- Python基础5 常用模块学习
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...
- linux centos7.5修改主机名和ip永久生效
以centos7.5为例 1.修改主机名 [root@localhost ~]# hostname localhost.localdomain[root@localhost ~]# hostname ...
- 11.vim编辑器命令
VI中的多行删除与复制 方法一: 单行删除,:1(待删除行)d 多行删除 ,:1,10d 方法二: 光标所在行,dd 光标所在行以下的N行,Ndd 方法1: 光标放到第6行, 输入:2yy ...
- localStorage本地存储的用法
localStorage用法 if(window.localStorage){ alert('这个浏览器支持本地存储'); }else{ alert('这个浏览器支持不本地存储'); } localS ...
- js人形时钟
https://blog.csdn.net/rsylqc/article/details/44808063 分享自:http://chabudai.org/blog/?p=59 在这个网站看到一个很有 ...
- DNS泛解析配置
多个域名走同一个nginx代理服务器,多个域名如果有相同的后缀,就可以使用泛解析了,配置如下 编辑文件:/etc/dnsmasq.conf address=/aa.com/172.16.10.10 a ...
- Pandas分类
Pandas分类 categorical data是指分类数据:数据类型为:男女.班级(一班.二班).省份(河北.江苏等),若使用赋值法给变量赋值,例如(男=1,女=0),数字1,0之间没有大小之分, ...
- HTML各种标签复习
<html> --开始标签 <head> 网页上的控制信息 <title>页面标题</title> </head> <bod ...
- ABAP 常用函数
函数名 描述 SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息EDIT_LINES 把READ_TEXT返回的LINES中的行按照TDFORMAT=“*”重新组织VI ...
- HTTP是用来做什么的
(一)HTTP协议介绍 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目 ...