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的点即 ...
随机推荐
- PHP中Notice: unserialize(): Error at offset of bytes in on line 的解决方法
使用unserialize函数将数据储存到数据库的时候遇到了这个报错,后来发现是将gb2312转换成utf-8格式之后,每个中文的字节数从2个增加到3个之后导致了反序列化的时候判断字符长度出现了问题, ...
- php中显示数组与对象的实现代码
1. 使用 print_r ( $array/$var ) print 是打印的意思,而r则取自Array的单词,那么该函数的功能就是打印数组内容,它既可以打印数组内容,也可以打印普通的变量. pri ...
- setTimeout闭包常见问题
经常会遇到这样的问题,setTimeout按序输出循环数字,而不是最后输出同一个数字: 题目: for (var i = 0; i < 5; i++) { setTimeout(function ...
- iOS 坐标转换
例:把A view上的某个点的坐标(a)转换到B view上,两种方法 CGPoint targetPointB = [A convertPoint:a toView:B];(记忆方法:把A上的某个点 ...
- java 线程状态相关测试
1. 启动netty server 等待接受客户端连接 package io.netty.example.myTest.nio; import java.io.IOException; import ...
- 微服务-springcloud
感觉微服务都差不多概念,最近稍微看了下springcloud,感觉入门还是很简单的,框架用用就那么回事,深入的话需要很多时间投入了 学一个东西,我推荐首先从概念上了解到他是做什么的,什么时候需要,基本 ...
- 437. Path Sum III
原题: 437. Path Sum III 解题: 思路1就是:以根节点开始遍历找到适合路径,以根节点的左孩子节点开始遍历,然后以根节点的右孩子节点开始遍历,不断循环,也就是以每个节点为起始遍历点 代 ...
- RunAsAdmin
program AdminCMD; {$APPTYPE CONSOLE} uses Windows, ShellApi, SysUtils; function RunAsAdmin(const ...
- Nodejs 第一站
Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js 是一个事件驱动I/O服务端JavaSc ...
- python判断任务是CPU密集型还是IO密集型
目前已经知道,在需要并发执行任务的时候,需要使用多线程或者多进程;如果是IO密集型任务,使用多线程,如果是CPU密集型任务,使用多进程;但问题是,经常我们会遇到一种情况就是:需要被执行的任务既有IO操 ...