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

给定n头牛,m个关系,每个关系a,b表示a认为b是受欢迎的,但是不代表b认为a是受欢迎的,关系之间还有传递性,假如a->b,b->c 则a->c,问有多少头牛被其他所有的牛欢迎.

统计出度为0的点,如果不为1,则表示不存在这样的牛,为1的话就输出这个集合点的数量.

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout); using namespace std;
#define N 10100
//N为最大点数
#define M 50100
//M为最大边数
int n, m;//n m 为点数和边数 struct Edge{
int from, to, nex;
bool sign;//是否为桥
}edge[M<<];
int head[N], edgenum;
void add(int u, int v){//边的起点和终点
Edge E={u, v, head[u], false};
edge[edgenum] = E;
head[u] = edgenum++;
} int DFN[N], Low[N], Stack[N], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)
int taj;//连通分支标号,从1开始
int Belong[N];//Belong[i] 表示i点属于的连通分支
bool Instack[N];
vector<int> bcc[N]; //标号从1开始 void tarjan(int u ,int fa){
DFN[u] = Low[u] = ++ Time ;
Stack[top ++ ] = u ;
Instack[u] = ; for (int i = head[u] ; ~i ; i = edge[i].nex ){
int v = edge[i].to ;
if(DFN[v] == -)
{
tarjan(v , u) ;
Low[u] = min(Low[u] ,Low[v]) ;
if(DFN[u] < Low[v])
{
edge[i].sign = ;//为割桥
}
}
else if(Instack[v]) Low[u] = min(Low[u] ,DFN[v]) ;
}
if(Low[u] == DFN[u]){
int now;
taj ++ ; bcc[taj].clear();
do{
now = Stack[-- top] ;
Instack[now] = ;
Belong [now] = taj ;
bcc[taj].push_back(now);
}while(now != u) ;
}
} void tarjan_init(int all){
memset(DFN, -, sizeof(DFN));
memset(Instack, , sizeof(Instack));
top = Time = taj = ;
for(int i=;i<=all;i++)if(DFN[i]==- )tarjan(i, i); //注意开始点标!!!
}
vector<int>G[N];
int du[N];
void suodian(){
memset(du, , sizeof(du));
for(int i = ; i <= taj; i++)G[i].clear();
for(int i = ; i < edgenum; i++){
int u = Belong[edge[i].from], v = Belong[edge[i].to];
if(u!=v)
{
G[u].push_back(v), du[u]++;
// printf("%d %d\n",u,v);
}
}
}
void init(){memset(head, -, sizeof(head)); edgenum=;}
int main()
{
//Read();
int a,b;
while(~scanf("%d%d",&n,&m))
{
init();
//scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
}
tarjan_init(n);
suodian();
int x=,j=;
for(int i=;i<=taj;i++)
{
if(du[i]==) x++,j=i; //出度为0点的个数
}
//printf("%d\n",j);
if(x!=) printf("0\n");
else
printf("%d\n",bcc[j].size());
}
return ;
}

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

开始题意理解不了,看了discuss,题意是说:

题目的意思是,sink中的点v如果能到w点,那么w点也必须能到v点,所以是所有出度为0的连通分量的点.

因为能互相到达的必在同一个连通分量.

依次判断1—n的点是不是出度为0的点,保存输出即可.

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout); using namespace std;
#define N 5100
//N为最大点数
#define M 150100
//M为最大边数
int n, m;//n m 为点数和边数 struct Edge{
int from, to, nex;
bool sign;//是否为桥
}edge[M<<];
int head[N], edgenum;
void add(int u, int v){//边的起点和终点
Edge E={u, v, head[u], false};
edge[edgenum] = E;
head[u] = edgenum++;
}
//DNF[i]表示遍历到第i点时,是第几次dfs
//Low[u] 表示 以u点为父节点的 子树 能连接到 [栈中] 最上端的点 的DFN值(换句话说,是最小的DFN,因为最上端的DFN是最小的嘛)
int DFN[N], Low[N], Stack[N], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)
int taj;//连通分支标号,从1开始
int Belong[N];//Belong[i] 表示i点属于的连通分支
bool Instack[N],flag;
vector<int> bcc[N]; //标号从1开始 void tarjan(int u ,int fa){
DFN[u] = Low[u] = ++ Time ;
Stack[top ++ ] = u ;
Instack[u] = ; for (int i = head[u] ; ~i ; i = edge[i].nex ){
int v = edge[i].to ;
if(DFN[v] == -)
{
tarjan(v , u) ;
Low[u] = min(Low[u] ,Low[v]) ;
if(DFN[u] < Low[v])
{
edge[i].sign = ;//为割桥
}
}
else if(Instack[v])
{
Low[u] = min(Low[u] ,DFN[v]) ;
if(DFN[v]!=Low[v]) flag=; //父节点还不是根节点
}
}
if(Low[u] == DFN[u]){
int now;
taj ++ ; bcc[taj].clear();
do{
now = Stack[-- top] ;
Instack[now] = ;
if(Belong[now]!=-) flag=; //每个节点都要只属于同一个联通分量
Belong [now] = taj ;
bcc[taj].push_back(now);
}while(now != u) ;
}
} void tarjan_init(int all){
memset(DFN, -, sizeof(DFN));
memset(Instack, , sizeof(Instack));
memset(Belong,-,sizeof(Belong));
top = Time = taj = ;
for(int i=;i<=all;i++)if(DFN[i]==- )tarjan(i, i); //注意开始点标!!!
}
vector<int>G[N];
int du[N];
void suodian(){
memset(du, , sizeof(du));
for(int i = ; i <= taj; i++)G[i].clear();
for(int i = ; i < edgenum; i++){
int u = Belong[edge[i].from], v = Belong[edge[i].to];
if(u!=v)
{
G[u].push_back(v), du[u]++;
// printf("%d %d\n",u,v);
}
}
}
void init(){memset(head, -, sizeof(head)); edgenum=;}
int p[N];
int main()
{
//Read();
int a,b;
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
init();
flag=;
while(m--)
{
scanf("%d%d",&a,&b);
add(a,b);
}
tarjan_init(n);
suodian();
int j=;
for(int i=;i<=n;i++)
{
if(du[Belong[i]]==)
p[j++]=i;
}
// printf("%d\n",j);
if(j==) {printf("\n");continue;}
for(int i=;i<j-;++i)
{
printf("%d ",p[i]);
}
printf("%d\n",p[j-]);
}
return ;
}

poj - 2186 Popular Cows && poj - 2553 The Bottom of a Graph (强连通)的更多相关文章

  1. 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)

    poj 2186 Popular Cows 题意: 有N头牛, 给出M对关系, 如(1,2)代表1欢迎2, 关系是单向的且能够传递, 即1欢迎2不代表2欢迎1, 可是假设2也欢迎3那么1也欢迎3. 求 ...

  2. poj 2186 Popular Cows (强连通分量+缩点)

    http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

  3. POJ 2186 Popular Cows (强联通)

    id=2186">http://poj.org/problem? id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 655 ...

  4. poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】

    题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Sub ...

  5. tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows

    缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...

  6. poj 2553 The Bottom of a Graph(强连通分量+缩点)

    题目地址:http://poj.org/problem?id=2553 The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K ...

  7. poj 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29908   Accepted: 12131 De ...

  8. POJ 2186 Popular Cows(Targin缩点)

    传送门 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31808   Accepted: 1292 ...

  9. [强连通分量] POJ 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31815   Accepted: 12927 De ...

随机推荐

  1. 用navcat编写定时任务调用存储过程

    最近项目需要改动比较大,数据库结构也有所改变,这时就需要转移旧数据到新库中 第一时间想到的是用代码操作,由于两个库表结构不同,实体什么的得需要重新生成 并编写转移代码,这将是很大的工作量: 然后就想着 ...

  2. 快学UiAutomator各种框架介绍

    Monkey 编写语言:命令行 运行环境:使用adb连接PC运行测试对象:Android平台自动化测试的一种手段,通过Monkey程序模拟用户触摸屏幕.滑动Trackball.按键等操作来对设备上的程 ...

  3. VC-基础:VC中得到当前系统的时间和日期

    得到当前时间的方法一般都是得到从1900年0点0分到现在的秒数,然后转为年月日时分秒的形式得到当前的时间(时分秒).主要方法如下: 1)使用CRT函数 C++代码   ]; time_t nowtim ...

  4. java程序-类的高级特性

    创建Employee类,在类中定义三个属性:编号,姓名,年龄,然后在构造方法里初始化这三个属性,最后在实现接口中的定义的CompareTo方法,将对象按编号升序排列. 代码如下:(程序可能有些错误,方 ...

  5. [CODEVS] 2189 数字三角形W

    数字三角形 要求走到最后mod 100最大 可达性DP(好像是这样叫) 用bool数组f[i][j][k]表示 位置(i,j)能否得到k(mod 100意义下) 转移条件 f[i][j][k]=f[i ...

  6. sql server存储过程修改,存储到mysql笔记

    由于有些项目要迁移到mysql上,数据迁移用MySQLWorkbench就能很好的迁移,最难的是存储过程之类的. 下面是sql server存储过程和mysql存储过程的转化: SQL SERVER: ...

  7. 离线功能对比:service worker和applicationCache

    SW 复杂,事件驱动,可以拦截请求,和缓存这些请求的响应数据,实现的效果更加灵活 AppCache 简单易用,声明式的将要缓存的文件清单声明在一个文件中.由于设计上的原因,它存在一些问题,导致难以运用 ...

  8. Python数据分析库之pandas,你该这么学!No.1

    写这个系列背后的故事 咦,面试系列的把基础部分都写完啦,哈哈答,接下来要弄啥嘞~ pandas吧 外国人开发的 翻译成汉语叫 熊猫 厉害厉害,很接地气 一个基于numpy的库 干啥的? 做数据分析用的 ...

  9. python爬取博客圆首页文章链接+标题

    新人一枚,初来乍到,请多关照 来到博客园,不知道写点啥,那就去瞄一瞄大家都在干什么好了. 使用python 爬取博客园首页文章链接和标题. 首先当然是环境了,爬虫在window10系统下,python ...

  10. Linux内核中的段属性

    #define __init __attribute__ ((__section__ (".init.text")))