Tarjan笔记1
Tarjan
2822 爱在心中
** 时间限制: 1 s
** 空间限制: 128000 KB
** 题目等级 : 钻石 Diamond
题解
题目描述 Description“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。”在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。
如果有这样一部分人,他们彼此都相爱,则他们就超越了一切的限制,用集体的爱化身成为一个爱心天使。
现在,我们想知道在这个爱的国度里会出现多少爱心天使。而且,如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的,否则输出-1。输入描述 Input Description第1行,两个数N、M,代表爱的国度里有N个人,爱的关系有M条。
第2到第M+1行,每行两个数A、B,代表A爱B。输出描述 Output Description第1行,一个数,代表爱的国度里有多少爱心天使。
第2行,如果某个爱心天使被其他所有人和爱心天使所爱则请输出这个爱心天使是由哪些人构成的(从小到大排序),否则输出-1。样例输入 Sample Input样例输入1:6 7
1 2
2 3
3 2
4 2
4 5
5 6
6 4
样例输入2:3 3
1 2
2 1
2 3样例输出 Sample Output样例输出1:2
2 3样例输出2:1
-1
codevs2282
1,求大小大于1的强联通个数,强联通缩点后,如果出度为0的强联通个数只有一个,输出这个强联通的元素,否则输出-1
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;
const int maxn = 1e5+7;
const int maxm = maxn << 2;
int n,m;
struct Node {
    int to,w,next;
} edge[maxm];
int first[maxn],sign;
int dfn[maxn],low[maxn],vis[maxn],inx,cnt,col[maxn],num[maxn];
int outdegree[maxn];
stack<int>s;
void clear_arr() {
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vis,0,sizeof(vis));
    memset(col,0,sizeof(col));
    memset(num,0,sizeof(num));
    memset(outdegree,0,sizeof(outdegree));
    inx = cnt = 1;
    while(s.size()) {
        s.pop();
    }
}
void init() {
    for(int i = 1; i <= n; i ++ ) {
        first[i] = 0;
    }
    sign = 1;
}
void add_edge(int u,int v,int w) {
    edge[sign].to = v;
    edge[sign].w  = w;
    edge[sign].next = first[u];
    first[u] = sign ++;
}
void tarjan(int x) {
    dfn[x] = low[x] = inx ++;
    s.push(x);
    vis[x] = 1;
    for(int i = first[x]; i ; i = edge[i].next ) {
        int to = edge[i].to;
        if(!dfn[to]) {
            tarjan(to);
            low[x] = min(low[x],low[to]);
        }
        else if(vis[to]) {
            low[x] = min(low[x],dfn[to]);
        }
    }
    int now;
    if(low[x] == dfn[x]) {
        do {
            now = s.top();
            s.pop();
            vis[now] = 0;
            col[now] = cnt;
            num[cnt] ++;
        } while(now != x);
        cnt ++;
    }
}
int main()
{
    int u,v,w;
    while(~scanf("%d %d",&n,&m)) {
        init();
        vector<pair<int,int> >vec;
        for(int i = 1; i <= m; i ++ ) {
            scanf("%d %d",&u,&v);
            add_edge(u,v,1);
            vec.push_back(make_pair(u,v));
        }
        clear_arr();
        for(int i = 1; i <= n; i ++ ) {
            if(!dfn[i]) {
                tarjan(i);
            }
        }
        int god = 0;
        for(int i = 1; i < cnt; i ++ ) {
            if(num[i] > 1) {
                god ++;
            }
        }
        printf("%d\n",god);
        for(int i = 0; i < vec.size(); i ++ ) {
            u = vec[i].first;
            v = vec[i].second;
            if(col[u] != col[v]) {
                outdegree[col[u]] ++;
            }
        }
        int pos = -1, number = 0;
        for(int i = 1; i < cnt ; i ++ ) {
            if(outdegree[i] == 0 && num[i] > 1) {
                pos = i;
                number ++;
            }
        }
        if(number == 1) {
            vector<int>ans;
            for(int i = 1; i <= n; i ++ ) {
                if(col[i] == pos) {
                    ans.push_back(i);
                }
            }
            for(int i = 0; i < ans.size(); i ++ ) {
                if(i == 0) {
                    printf("%d",ans[i]);
                } else {
                    printf(" %d",ans[i]);
                }
            }
            puts("");
        } else {
            puts("-1");
        }
    }
    return 0;
}												
											Tarjan笔记1的更多相关文章
- tarjan复习笔记
		
tarjan复习笔记 (关于tarjan读法,优雅一点读塔洋,接地气一点读塔尖) 0. 连通分量 有向图: 强连通分量(SCC)是个啥 就是一张图里面两个点能互相达到,那么这两个点在同一个强连通分量里 ...
 - $tarjan$简要学习笔记
		
$QwQ$因为$gql$的$tarjan$一直很差所以一直想着要写个学习笔记,,,咕了$inf$天之后终于还是写了嘻嘻. 首先说下几个重要数组的基本定义. $dfn$太简单了不说$QwQ$ 但是因为有 ...
 - [学习笔记]tarjan求割点
		
都口胡了求割边,就顺便口胡求割点好了QAQ 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访问,并在回溯后更新 2.如果某个邻接点已被访问过,则更新 对于当前 ...
 - [学习笔记]tarjan求割边
		
上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...
 - [Tarjan 学习笔记](无向图)
		
今天考试因为不会敲 Dcc 的板子导致没有AK(还不是你太菜了),所以特地写一篇博客记录 Tarjan 的各种算法 无向图的割点与桥 (各种定义跳过) 割边判定法则 无向边 (x,y) 是桥,当且仅当 ...
 - Tarjan学习笔记
		
\(Tarjan\)是个很神奇的算法. 给一张有向图,将其分解成强连通分量们. 强连通分量的定义:一个点集,使得里面的点两两可以互相到达,并且再加上另一个点都无法满足强连通性. \(Tarjan\)的 ...
 - Tarjan/2-SAT学习笔记
		
Tarjan/2-SAT Tags:图论 作业部落 评论地址 Tarjan 用来求割边或者割点,求点双联通分量或者边双联通分量 点双联通分量:两个点之间有两条点不相交的路径 边双联通分量:两个点之间有 ...
 - 强连通分量(Korasaju & Tarjan)学习笔记
		
好久以前学过的东西...现在已经全忘了 很多图论问题需要用到强连通分量,还是很有必要重新学一遍的 强连通分量(Strongly Connected Component / SCC) 指在一个有向图中, ...
 - 算法笔记_146:TarJan算法的应用(Java)
		
目录 1 问题描述 2 解决方案 1 问题描述 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M& ...
 
随机推荐
- Android 6.0 以后webview不加载图片的问题
			
/** * Webview在安卓5.0之前默认允许其加载混合网络协议内容 * 在安卓5.0之后,默认不允许加载http与https混合内容,需要设置webview允许其加载混合网络协议内容 */if ...
 - show engine innodb status输出说明
			
参考链接 (https://dev.mysql.com/doc/refman/5.7/en/innodb-standard-monitor.html) 其中有这样一句: For a descripti ...
 - mysql导出与导入
			
环境 centos6.5 32位 Mysql 5.7.19 导出 mysqldump用法 导出整个数据库 [root@mini2 mysql]# mysqldump -p123456 --databa ...
 - css3 flex 布局
			
今天做一个小实战,需要让一个登录框始终保持水平和垂直居中,第一个想到的就是通过定位(要想让一个div居中,采用定位可以解决,示例), 然后开始接触flex布局,学完感觉真的好用,现把知识点记录一下,以 ...
 - 【webGL入门2】点线面的绘制
			
用js绘制webGL的点: THREE.Vector3 = function ( x, y, z ) { //用THREE声明的变量都是全局变量.this.x = x || 0;this.y = y ...
 - [CodeForces10D]LCIS(最长公共上升子序列) - DP
			
Description 给定两个数列,求最长公共上升子序列,并输出其中一种方案. Input&Output Input 第一行一个整数n(0<n<=500),数列a的长度. 第二行 ...
 - 关于CheckStyle在eclipse出现的问题
			
今天在公司换了一个CheckStyle xml文件.那么我尝试直接import进去新的文件. 在我Check code的时候就爆了下面的错误 o: Failed during checkstyle c ...
 - AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle
			
https://beta.atcoder.jp/contests/abc075/tasks/abc075_d 题意: 给出坐标平面上n个点的坐标,要求找到一个面积最小的矩形使得这个矩形的边界加上内部的 ...
 - POJ-1122 FDNY to the Rescue!---Dijkstra+反向建图
			
题目链接: https://vjudge.net/problem/POJ-1122 题目大意: 给出矩阵,矩阵中每个元素tij表示从第i个交叉路口到第j个交叉路口所需时间,若tij为-1则表示两交叉路 ...
 - 前端开发必备之Chrome开发者工具(下篇)
			
本文介绍的 Chrome 开发者工具基于 Chrome 65版本,如果你的 Chrome 开发者工具没有下文提到的那些内容,请检查下 Chrome 的版本 本文是 前端开发必备之Chrome开发者工具 ...