tarjan+缩点+强连通定理

C - Network of Schools

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d
& %I64u

Submit Status

Description

A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B is in the distribution list of school
A, then A does not necessarily appear in the list of school B

You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that
by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made
so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.

Input

The first line contains an integer N: the number of schools in the network (2 <= N <= 100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers
of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.

Output

Your program should write two lines to the standard output. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.

Sample Input

5
2 4 3 0
4 5 0
0
0
1 0

Sample Output

1

2

这个题最大的难点在于任务二,任务二的意思就是添加最少的边使一个有向图变成强连通图,有一个定理是max(n,m)其中n是出度为0的点的个数,m是入度为0的点的个数,当然,如果这个图是强连通图的话,就需要讨论了,这时答案就是0了。将第二个问题解决掉,这个题就是一个模板题了,但是我现在仍没有证明这个命题的正确性!有大神说显然,我觉得应该可以证出来,希望看到这个博客的大神可以帮帮忙,谢谢。
#include<stdio.h>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
int dfn[120];
int belong[120],bnt,instack[120];
int index,out[120],in[120],low[120];
int map[120][120];
stack<int>S;
void tarjan(int i){
	dfn[i] = low[i] = ++index;
	S.push(i);
	instack[i] = 1;
	for(int j = 1;j<=map[i][0];j++){
		int k = map[i][j];
		if(!dfn[k]){
			tarjan(k);
			low[i] = min(low[i],low[k]);
		}
		else if(instack[k])
		low[i] = min(low[i],dfn[k]);
	}
	if(low[i] == dfn[i]){
		bnt++;
		int j;
		do{
			j = S.top();
			S.pop();
			instack[j] = 0;
			belong[j] = bnt;
		}while(i!=j);
	}
}
int main(){
	int n,m,ans,ans1;
	while(~scanf("%d",&n)){
		memset(dfn,0,sizeof(dfn));
		memset(low,0,sizeof(low));
		memset(instack,0,sizeof(instack));
		memset(out,0,sizeof(out));
		memset(in,0,sizeof(in));
		memset(map,0,sizeof(map));
		bnt = index = 0;
		ans = ans1 = 0;
		for(int i=1;i<=n;i++){
			while(scanf("%d",&m),m)
			if(m)map[i][++map[i][0]] = m;
		}
		for(int i=1;i<=n;i++)
		if(!dfn[i])tarjan(i);
		for(int i=1;i<=n;i++){
			for(int j = 1;j<=map[i][0];j++){
				if(belong[i]!=belong[map[i][j]]){
				out[belong[i]]++;
				in[belong[map[i][j]]]++;
				}
			}
		}
		for(int i=1;i<=bnt;i++){
			if(out[i]==0)ans++;
			if(in[i]==0)ans1++;
		}
		printf("%d\n",ans1);
		if(bnt ==1)printf("0\n");
		else printf("%d\n",max(ans1,ans));
	}
} 

tarjan+缩点+强连通定理

时间: 2024-10-10 02:29:50

tarjan+缩点+强连通定理的相关文章

POJ2533&amp;&amp;SP1799 The Bottom of a Graph(tarjan+缩点+强连通分量)

POJ2553 SP1799 我们知道单独一个强连通分量中的所有点是满足题目要求的 但如果它连出去到了其他点那里,要么成为新的强连通分量,要么失去原有的符合题目要求的性质 所以只需tarjan缩点求出所有强连通分量,再O(E)枚举所有边,是否会成为连接一个分量与另一个分量的边--即一条出度--即可 如果一个分量没有出度,那么他中间的所有点都是符合题目要求的点 (因为快读快输加了太长所以就不贴了) const int N=5005,M=N*N>>1; int h[N],en,n,m,dfn[N]

强连通分量tarjan缩点——POJ2186 Popular Cows

这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定意味着v可达u.    相互可达则属于同一个强连通分量    (Strongly Connected Component, SCC) §有向图和它的转置的强连通分量相同 §所有SCC构成一个DAG(有向无环图) dfn[u]为节点u搜索的次序编号(时间戳),即首次访问u的时间 low[u]为u或u的

POJ 1236 Network of Schools(强连通 Tarjan+缩点)

POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入?几条边使得有向图成为一个强连通图. 分析: 跟HDU 2767 Proving Equivalences(题解)一样的题目,只是多了个问题,事实上转化成DAG后就不难考虑了,事实上仅仅要选择入度为0的点即可了. 代码: /* * Author: illuz <iilluzen[at]gmail.com> *

HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)

HDU 2767 Proving Equivalences(强连通 Tarjan+缩点) ACM 题目地址:HDU 2767 题意: 给定一张有向图,问最少添加几条边使得有向图成为一个强连通图. 分析: Tarjan入门经典题,用tarjan缩点,然后就变成一个有向无环图(DAG)了. 我们要考虑的问题是让它变成强连通,让DAG变成强连通就是把尾和头连起来,也就是入度和出度为0的点. 统计DAG入度和出度,然后计算头尾,最大的那个就是所求. 代码: /* * Author: illuz <iil

UvaLive4287 roving Equivalences(Tarjan缩点+DAG)

UvaLive4287 roving Equivalences 题意:给n个定理,以及m个关系,即u定理可以推出v定理.问至少还需要加多少个条件,才能是定理两两互推. 思路:Tarjan缩点.然后变成一个DAG.ans1记录入度为0的联通块,ans2记录出度为0的联通块.输出较大值即可.注意如果点数为1或者只有一个强连通分量要输出0. /* ID: onlyazh1 LANG: C++ TASK: Knights of the Round Table */ #include<iostream>

【BZOJ-1797】Mincut 最小割 最大流 + Tarjan + 缩点

1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1685  Solved: 724[Submit][Status][Discuss] Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路,需要代价ci.现在B国想找出一个路径切断方案

[BZOJ 1051][HAOI 2006]受欢迎的牛(tarjan缩点)

http://www.lydsy.com:808/JudgeOnline/problem.php?id=1051 唔...这题好像在POJ上见过? 比较水的题,很好想出思路.牛和牛之间的关系就像有向图,牛a喜欢牛b相当于建立有向边a->b,然后在这个有向图中,每个强连通分量里的牛们相当于是相互喜欢的,把这个图缩点成DAG,DAG里如果有且仅有一个出度为0的点,则这个点对应强连通分量里的所有牛都是受欢迎的牛,如果没有出度为0的点,当然就没受欢迎的牛了,如果出度为0的点的个数大于1,则每个出度为0的

【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率

2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1638  Solved: 433[Submit][Status][Discuss] Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌

UVA11504- Dominos(Tarjan+缩点)

题目链接 题意:多米诺骨牌的游戏,给出一些牌,以及哪张牌倒了之后会推倒哪张牌,求最少的推倒牌的张数,使得所有牌都倒下去. 思路:有向图的强连通分量,用Tarjan缩点之后找出入度为0的点的个数,即为答案. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 100100;