poj 1236+hdu2767 有向图 缩点+看度数(tarjan)
1236题意:一个有向图,1,求至少从几个点出发可以遍历该图,2:,求至少添加多少边,使强连通。而,HDU的只有后面一问。
解;先缩点,第一问只需找所有入度为0的点即可。,第2问,max(入度为0的点,出度为0点)。也写了2个小时。。虽然1A,但是因为细节卡了,不应该。
代码详细说:
#include<iostream> //0ms 1A poj1236
#include<vector>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int n;
vector<vector<int> >edges(101);
int visited[101];
int low[101];
int dfn[101];
int ind[101];int outd[101]; //统计出入度
int Strongly_connected_branch[101]; //并为一个强连通,标记为1.2.3...
int num;int times;
stack<int>s;
bool instack[101];
void tarjan(int u) //dfs
{
low[u]=dfn[u]=times++;
instack[u]=1;
s.push(u);
int len=edges[u].size();
for(int i=0;i<len;i++)
{
int v=edges[u][i];
if(visited[v]==0) //小心细节!
{
visited[v]=1;
tarjan(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&low[u]>dfn[v]) //有向图,要问是否在栈中,后向边,V为U某个祖先
{
low[u]=dfn[v];
}
}
if(dfn[u]==low[u]) //在一个SCC
{
num++;int temp;
do
{
temp=s.top();
instack[temp]=0;
s.pop();
Strongly_connected_branch[temp]=num;
} while(temp!=u);
}
}
void readin() //读入数据
{
scanf("%d",&n);
int to;
for(int i=1;i<=n;i++)
{
scanf("%d",&to);
while(to!=0)
{
edges[i].push_back(to);
scanf("%d",&to);
}
}
}
int ind0,outd0;
void initialize() //初始化
{
ind0=outd0=num=times=0;
}
void solve()
{
for(int i=1;i<=n;i++) //原图未必连通
if(visited[i]==0)
{
visited[i]=1;
tarjan(i);
}
for(int i=1;i<=n;i++) //自己思得:枚举所有边,在不同scc中的,这样统计其出入度,缩点只是把所有SCC分开
{ //这样统计,出入度为0的肯定没问题,但是是收缩后的图(原图中有几条边SCC间连任连几条)的出入度,
int len=edges[i].size();
for(int j=0;j<len;j++)
{
int v=edges[i][j];
if(Strongly_connected_branch[v]!=Strongly_connected_branch[i])
{
outd[Strongly_connected_branch[i]]++;
ind[Strongly_connected_branch[v]]++;
}
}
}
for(int i=1;i<=num;i++)
{
//cout<<"out:"<<outd[i]<<"in:"<<ind[i]<<endl;
if(outd[i]==0)outd0++;
if(ind[i]==0)ind0++;
}
}
int main()
{
readin();
initialize();
solve();
int max0=outd0;
if(num==1){printf("1\n0\n");return 0 ;} //如果原来就强连通,特判
if(ind0>max0)max0=ind0;
printf("%d\n%d\n",ind0,max0);
return 0;
}
#include<iostream> //hdu 260ms
#include<vector>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int n;int m;
vector<vector<int> >edges(20001);
int visited[20001];
int low[20001];
int dfn[20001];
int ind[20001];int outd[20001]; //统计出入度
int Strongly_connected_branch[20001]; //并为一个强连通,标记为1.2.3...
int num;int times;
stack<int>s;
bool instack[20001];
void tarjan(int u)
{
low[u]=dfn[u]=times++;
instack[u]=1;
s.push(u);
int len=edges[u].size();
for(int i=0;i<len;i++)
{
int v=edges[u][i];
if(visited[v]==0)
{
visited[v]=1;
tarjan(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&low[u]>dfn[v]) //有向图,要问是否在栈中,后向边,V为U某个祖先
{
low[u]=dfn[v];
}
}
if(dfn[u]==low[u]) //在一个SCC
{
num++;int temp;
do
{
temp=s.top();
instack[temp]=0;
s.pop();
Strongly_connected_branch[temp]=num;
} while(temp!=u);
}
}
void readin()
{
scanf("%d%d",&n,&m);
int from,to;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&from,&to);
edges[from].push_back(to);
}
}
int ind0,outd0;
void initialize() //多组数据,必需初始化
{
ind0=outd0=num=times=0;
for(int i=0;i<=n;i++)
{
instack[i]=low[i]=dfn[i]=visited[i]=ind[i]=outd[i]=0;
edges[i].clear();
Strongly_connected_branch[i]=-1;
}
}
void solve()
{
for(int i=1;i<=n;i++)
if(visited[i]==0)
{
visited[i]=1;
tarjan(i);
}
for(int i=1;i<=n;i++) //自己思得:枚举所有边,在不同scc中的,这样统计其出入度,缩点只是把所有SCC分开
{ //这样统计,出入度为0的肯定没问题,但是是收缩后的图(原图中有几条边SCC间连任连几条)的出入度,
int len=edges[i].size();
for(int j=0;j<len;j++)
{
int v=edges[i][j];
if(Strongly_connected_branch[v]!=Strongly_connected_branch[i])
{
outd[Strongly_connected_branch[i]]++;
ind[Strongly_connected_branch[v]]++;
}
}
}
for(int i=1;i<=num;i++)
{
if(outd[i]==0)outd0++;
if(ind[i]==0)ind0++;
}
}
int main()
{
int tcase;
scanf("%d",&tcase);
while(tcase--)
{
initialize();
readin();
solve();
int max0=outd0;
if(num==1){printf("0\n");continue;}
if(ind0>max0)max0=ind0;
printf("%d\n",max0);
}
return 0;
}
poj 1236+hdu2767 有向图 缩点+看度数(tarjan)的更多相关文章
- hdu 1827 有向图缩点看度数
题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...
- POJ 1236 Network of Schools(强连通分量/Tarjan缩点)
传送门 Description A number of schools are connected to a computer network. Agreements have been develo ...
- POJ 1236 Network of Schools(Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16806 Accepted: 66 ...
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...
- 有向图 加最少的边 成为强连通分量的证明 poj 1236 hdu 2767
poj 1236: 题目大意:给出一个有向图, 任务一: 求最少的点,使得从这些点出发可以遍历整张图 任务二: 求最少加多少边 使整个图变成一个强连通分量. 首先任务一很好做, 只要缩点 之后 求 ...
- POJ 1236 Network of Schools - 缩点
POJ 1236 :http://poj.org/problem?id=1236 参考:https://www.cnblogs.com/TnT2333333/p/6875680.html 题意: 有好 ...
- POJ 1236 Network of Schools(强连通分量)
POJ 1236 Network of Schools 题目链接 题意:题意本质上就是,给定一个有向图,问两个问题 1.从哪几个顶点出发,能走全全部点 2.最少连几条边,使得图强连通 思路: #inc ...
- POJ 1236——Network of Schools——————【加边形成强连通图】
Network of Schools Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u ...
- Poj 1236 Network of Schools (Tarjan)
题目链接: Poj 1236 Network of Schools 题目描述: 有n个学校,学校之间有一些单向的用来发射无线电的线路,当一个学校得到网络可以通过线路向其他学校传输网络,1:至少分配几个 ...
随机推荐
- check_http.c:312: error: ‘ssl_version’
安装nagios-plugins-1.4.16,安装的过程中出现了错误,提示如下.check_http.c:312: error: ‘ssl_version’ undeclared (first us ...
- Javaweb学习笔记2—Tomcat和http协议
今天来讲javaweb的第二个阶段学习. 老规矩,首先先用一张思维导图来展现今天的博客内容. ps:我的思维是用的xMind画的,如果你对我的思维导图感兴趣并且想看到你们跟详细的备注信息,请点击下 ...
- 登录脚本重构by封装
package com.gubai.selenium; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; imp ...
- ios水果风暴游戏源码项目下载
这是一款ios水果风暴游戏源码下载,介绍给大家一下,喜欢的朋友可以下载学习一下吧.应用介绍:这是一个以获得高分和挑战更高难度为目的的游戏.游戏中有九种不同的卡通水果,您可以交换屏幕中两个相邻水果的位置 ...
- Servlet 3.0 新特性详解 (转载)
原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/ Servlet 3.0 新特性概述 Servlet 3.0 作为 Jav ...
- G7或变G6+1?特朗普七国峰会箱友军开炮
今日导读 G7 峰会刚召开完毕,德国总理默克尔发的一张照片就迅速火遍全球.照片中她身体前倾,像是在质问特朗普,而后者则双手交叉胸前,我自岿然不动,这张火药味十足的照片不禁让人脑补当时剑拔弩张的气氛.到 ...
- C-基础:函数返回局部变量
一般的来说,函数是可以返回局部变量的. 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了.因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错.但是如果返回的是局部变量的地 ...
- BZOJ3940: [Usaco2015 Feb]Censoring (AC自动机)
题意:在文本串上删除一些字符串 每次优先删除从左边开始第一个满足的 删除后剩下的串连在一起重复删除步骤 直到不能删 题解:建fail 用栈存当前放进了那些字符 如果可以删 fail指针跳到前面去 好菜 ...
- react笔记汇总
1.什么是React? a.React 是一个用于构建用户界面的 JAVASCRIPT 库. b.React主要用于构建UI,很多人认为 React 是 MVC 中的 V. c.React 起源于 F ...
- POJ-1724 深搜剪枝
这道题目如果数据很小的话.我们通过这个dfs就可以完成深搜: void dfs(int s) { if (s==N) { minLen=min(minLen,totalLen); return ; } ...