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:至少分配几个 ...
随机推荐
- spring @value 为什么没有获取到值
1.配置文件的路径没有扫描到 2.注解的bean 不是通过spring托管的.bean 要通过spring 注解,引用的时候要用@Autowired 自动注入的bean 不要用new 出来的bean ...
- Python3简明教程(九)—— 文件处理
文件是保存在计算机存储设备上的一些信息或数据.你已经知道了一些不同的文件类型,比如你的音乐文件,视频文件,文本文件.Linux 有一个思想是“一切皆文件”,这在实验最后的 lscpu 的实现中得到了体 ...
- react开启一个项目 webpack版本出错
npx create-react-app my-app cd my-app npm start 在命令行里执行以上语句就可(前两天刚刚发现,最新版的react对webpack的版本要了新要求,大概是他 ...
- libcmt.lb libcmtd.lib与MSVCRTD.lib的冲突解决
system("pause"); 这个函数存在于MSVCRTD.lib库中: 当要使用system("pause")这个函数,且libcmt.lb libcmt ...
- MFC限制窗口大小
MFC限制窗口大小 使用:WM_GETMINMAXINFO message void OnGetMinMaxInfo(MINMAXINFO* lpMMI) { lpMMI->ptMinTrack ...
- L_01 网络字节顺序
(1)计算机在存储多字节数据时存在大端字节顺序和小端字节顺序两种方式. 大端:高位字节排放在内存的低地址端(即该值的起始地址),低位字节排放在内存的高地址端. 小端:低位字节排放在内存的低地址端(即该 ...
- QT5:第二章 布局排版控件
一.简介 在QT组件面板中有Layouts和Spacers两个组件面板 注意:布局排版控件不显示 1.Layouts(布局) Vertical Layout:垂直方向布局,组件自动在垂直方向上分布 H ...
- No-4.文件和目录常用命令
文件和目录常用命令 结构 查看目录内容 ls 切换目录 cd 创建和删除操作 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 ...
- Mysql+MHA高可用集群
http://www.ttlsa.com/mysql/step-one-by-one-deploy-mysql-mha-cluster/
- Haybale Stacking(差分数组 + 求中位数的一些方法 + nth_element)
题意: 给定N个初始值为0的数, 然后给定K个区间修改(区间[l,r] 每个元素加一), 求修改后序列的中位数. 分析: K个离线的区间修改可以使用差分数组(http://www.cnblogs.co ...