POJ2186(有向图缩点)
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 28379 | Accepted: 11488 |
Description
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.
Input
* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.
Output
Sample Input
3 3
1 2
2 1
2 3
Sample Output
1
题意:A认为B受欢迎,B认为C受欢迎,那么A就认为C受欢迎。给定N头牛,M个认为受欢迎情况。确定受所有牛欢迎的这些牛的数目。
思路:首先判断有向图是否连通,若不连通则答案为0。若连通则进行缩点(注意有向图与无向图的缩点的不同之处),缩点之后得到一个有向树。若树中存在多个叶子结点,则答案为0,否则答案为 缩成叶子结点的那个连通分量重结点的数目。
下面是第二种有向图缩点方法,一次dfs,边反向后再进行一次rdfs.解释见代码
#include"cstdio"
#include"cstring"
#include"vector"
using namespace std;
const int MAXN=;
int V,E;
vector<int> G[MAXN];
vector<int> rG[MAXN];
vector<int> vs;
bool used[MAXN];
int cmp[MAXN];
void add_edge(int u,int v)
{
G[u].push_back(v);
rG[v].push_back(u);
}
void dfs(int u)
{
used[u]=true;
for(int i=;i<G[u].size();i++)
if(!used[G[u][i]]) dfs(G[u][i]);//假设u所能访问的结点都处于同一连通分量
vs.push_back(u); //后续遍历
}
void rdfs(int u,int k)
{
used[u]=true;
cmp[u]=k;
for(int i=;i<rG[u].size();i++)
if(!used[rG[u][i]]) rdfs(rG[u][i],k);
}
int scc()
{
memset(used,false,sizeof(used));
for(int i=;i<=V;i++)
if(!used[i]) dfs(i);
memset(used,false,sizeof(used));
int k=;
for(int i=vs.size()-;i>=;i--)//倒着访问,保证边反向后各个连通分量互不影响
if(!used[vs[i]]) rdfs(vs[i],k++);//对应后续遍历,若边反向后,起点u仍能遍历整个连通分量,那么它们处以同一连通分量中.否则处于不同的连通分量
return k;
}
int deg[MAXN];
int seek()
{
memset(deg,,sizeof(deg));
int k=scc();
for(int i=;i<=V;i++)
for(int j=;j<G[i].size();j++)
{
int to=G[i][j];
if(cmp[i]!=cmp[to])
{
deg[cmp[i]]++;
}
} int v=-;
int flag=;
int ans=;
for(int i=;i<=V;i++)
if(deg[cmp[i]]==)
{
ans++;
if(cmp[i]!=v)
{
v=cmp[i];
flag++;
}
if(flag>) return ;
}
return ans;
}
int main()
{
while(scanf("%d%d",&V,&E)!=EOF)
{
for(int i=;i<=V;i++)
{
vs.clear();
G[i].clear();
rG[i].clear();
cmp[i]=;
}
for(int i=;i<E;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
int ans=seek();
printf("%d\n",ans);
} return ;
}
标准tarjan算法对有向图缩点。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=;
vector<int> mp[MAXN];
int n,m;
int dfn[MAXN],low[MAXN],time;
int stack[MAXN],top;
bool ins[MAXN];
int belong[MAXN],cnt;
void dfs(int u)
{
dfn[u]=low[u]=++time;
stack[top++]=u;
ins[u]=true;
for(int i=;i<mp[u].size();i++)
{
int v=mp[u][i];
if(!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(ins[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
cnt++;
int v;
do{
v=stack[--top];
belong[v]=cnt;
ins[v]=false;
}while(u!=v);
}
}
int deg[MAXN];
void cal()
{
memset(deg,,sizeof(deg));
int res=;
for(int i=;i<=n;i++)
for(int j=;j<mp[i].size();j++)
{
int v=mp[i][j];
if(belong[i]!=belong[v])
{
deg[belong[i]]++;
}
}
int mark;
for(int i=;i<=cnt;i++)
if(deg[i]==)
{
mark=i;
res++;
}
if(res!=)
{
printf("0\n");
return;
}
res=;
for(int i=;i<=n;i++)
if(belong[i]==mark)
res++;
printf("%d\n",res);
}
int main()
{ while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<=n;i++)
mp[i].clear();
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
time=;
top=;
cnt=;
memset(ins,false,sizeof(ins));
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
mp[u].push_back(v);
} for(int i=;i<=n;i++)
if(!dfn[i])
dfs(i);
cal();
}
return ;
}
POJ2186(有向图缩点)的更多相关文章
- hdu 3072 有向图缩点成最小树形图计算最小权
题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ...
- HDU1269(有向图缩点模板题)
迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- POJ2553( 有向图缩点)
The Bottom of a Graph Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9779 Accepted: ...
- POJ1904(有向图缩点+输入输出挂参考)
King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 8311 Accepted: 3017 Cas ...
- hdu 1827 有向图缩点看度数
题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...
- HDU 4635 (完全图 和 有向图缩点)
题目链接:HDU 4635 题目大意: 给你一个有向图,加有向边,使得这个图是简单有向图.问你最多加多少条有向边. 简单有向图: 1.不存在有向重边. 2.不存在图循环.(注意是不存在 “图” 循环 ...
- 对Tarjan——有向图缩点算法的理解
开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...
- hdu 3639 有向图缩点+建反向图+搜索
题意:给个有向图,每个人可以投票(可以投很多人,一次一票),但是一个人只能支持一人一次,支持可以传递,自己支持自己不算,被投支持最多的人. 开始想到缩点,然后搜索,问题是有一点想错了!以为支持按票数计 ...
- poj2553 有向图缩点,强连通分量。
//求这样的sink点:它能达到的点,那个点必能达到他,即(G)={v∈V|任意w∈V:(v→w)推出(w→v)} //我法:tarjan缩点后,遍历点,如果该点到达的点不在同一个强连通中,该点排除, ...
随机推荐
- 五个知识体系之-SQL学习-第二天
创建数据:INSERT INTO userinfo(userid,username,job,level1,companyage) VALUES ('001','xl001','test','P1',' ...
- 【BZOJ1115】[POI2009]石子游戏Kam 阶梯博弈
[BZOJ1115][POI2009]石子游戏Kam Description 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要 ...
- ThreadLocal的简单使用
package com.thread; public class ThreadLocalTest { public static void main(String[] args) { final Pe ...
- windowsphone8.1学习笔记之应用数据(一)
数据存储分为两种:云存储和应用数据(即本地存储),wp中的应用数据分为两种,一种是应用设置:一种是应用文件.wp的数据相关都是通过ApplicationData来实现,一个程序只有数据存储区. 先说应 ...
- 九度OJ 1161:Repeater(复制器) (递归)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1449 解决:508 题目描述: Harmony is indispensible in our daily life and no one ...
- Netty Bootstrap(图解)|秒懂
目录 Netty Bootstrap(图解) 源码工程 写在前面 图解几个重要概念 父子 channel EventLoop 线程与线程组 通道与Reactor线程组 Channel 通道的类型 启动 ...
- 如何在windows上创建文件名以“.”开头的文件
比如要创建.env文件,正常会提示必须输入文件名才能创建的,但是可以在后面再加一个点就能创建了,.env.这样就可以了
- 【Xcode学C-4】进制知识、位运算符、变量存储细节以及指针的知识点介绍
一.进制知识 (1)默认是十进制.八进制前面加0.即int num1=015;是13.十六进制前面加0x/0X.即int num1=0xd.结果是13.二进制前面是0b/0B,即int num1=0b ...
- SVN支干合并(转载)
分支用来维护独立的开发支线,在一些阶段,你可能需要将分支上的修改合并到最新版本,或者将最新版本的修改合并到分支. 此操作十分重要,在团队开发中,如果你是SVN 的维护者此环节可以说是必不可少,因为团队 ...
- SAP流水号
[转]编号范围对象维护 Tcode: SNRO OYSM 1.Number Range的通用Tcode:SNRO 2.Number Range的通用读取函数:NUMBER_GET_NEXT 3 ...