图论,求有向图的强连通分支

来源:互联网 发布:疯狂java讲义好不好 编辑:程序博客网 时间:2024/04/26 20:25

求有向图的强联通分支十一个典型的图论题目。
本来想把他写成一个通用的算法,但是发现有很多不太好处理的地方,比如选用邻接链表还是选用邻接矩阵来表示图,有的情况是不一样的,再者很难把强联通分支缩点,并且再构建一个图出来,主要是强联通分支之间的边表示的时候要考虑一些情况,比如边的费用什么的。
但是也可以尝试做一个稍微通用的一点的算法,就是把所有点属于那个强连通标识(用id[i]表示)出来。
如果对于原图中两点i,j。 如果id[i]==id[j],则他们在一个强联通分支中,否则他们一定不在一个强联通分支中。至于确定两个不同强连通分支之间的关系,就留给客户去做,就好了。
先给出pku的一个题目,使用了求强联通分支的技术。

The Bottom of a Graph

Description
We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called vertices (or nodes). Let E be a subset of the Cartesian product V×V, its elements being called edges. Then G=(V,E) is called a directed graph.
Let n be a positive integer, and let p=(e1,...,en) be a sequence of length n of edges ei∈E such that ei=(vi,vi+1) for a sequence of vertices (v1,...,vn+1). Then p is called a path from vertex v1 to vertex vn+1 in G and we say that vn+1 is reachable from v1, writing (v1→vn+1).
Here are some new definitions. A node v in a graph G=(V,E) is called a sink, if for every node w in G that is reachable from v, v is also reachable from w. The bottom of a graph is the subset of all nodes that are sinks, i.e., bottom(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}. You have to calculate the bottom of certain graphs.

Input
The input contains several test cases, each of which corresponds to a directed graph G. Each test case starts with an integer number v, denoting the number of vertices of G=(V,E), where the vertices will be identified by the integer numbers in the set V={1,...,v}. You may assume that 1<=v<=5000. That is followed by a non-negative integer e and, thereafter, e pairs of vertex identifiers v1,w1,...,ve,we with the meaning that (vi,wi)∈E. There are no edges other than specified by these pairs. The last test case is followed by a zero.

Output
For each test case output the bottom of the specified graph on a single line. To this end, print the numbers of all nodes that are sinks in sorted order separated by a single space character. If the bottom is empty, print an empty line.

Sample Input

3 3
1 3 2 3 3 1
2 1
1 2
0

Sample Output

1 3


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class Main
{

static LinkedList [] mapa;
static LinkedList [] mapt;
static int [] order;
static int tag;
static boolean [] vst;
static int [] id;
static int [] id_degree_cnt;
public static void main(String[] args) throws IOException
{
BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
while(true)
{
int n=0,m=0;
try
{
String s=cin.readLine().trim();
String [] sa=s.split(" +");
n=Integer.parseInt(sa[0]);
if(n==0)break;
m=Integer.parseInt(sa[1]);
mapa=new LinkedList[n];
mapt=new LinkedList[n];
for(int i=0;i<n;i++)
{
mapa[i]=new LinkedList<Integer>();
mapt[i]=new LinkedList<Integer>();
}
if(m>=0)
{
s=cin.readLine().trim();
sa=s.split(" +");
}
else sa=new String[] {};
for(int i=0;i<sa.length;i+=2)
{
int from=Integer.parseInt(sa[i])-1;
int to=Integer.parseInt(sa[i+1])-1;
mapa[from].add(to);
mapt[to].add(from);
}
}catch(Exception e)
{

}

order=new int[n];
tag=0;
vst=new boolean[n];
for(int i=0;i<n;i++)
if(vst[i]==false)
{
vst[i]=true;
dfsa(i);
}
id=new int[n];
tag=0;
Arrays.fill(vst,false);
for(int i=n-1;i>=0;i--)
{
if(vst[order[i]]==false)
{
vst[order[i]]=true;
dfst(order[i]);
tag++;
}
}
id_degree_cnt=new int[tag];
for(int i=0;i<n;i++)
{
LinkedList ll=mapa[i];
for(int j=0;j<ll.size();j++)
{
int next=(Integer)ll.get(j);
if(id[i]!=id[next])
id_degree_cnt[id[i]]++;
}
}
List<Integer>rel=new ArrayList<Integer>(n);
for(int i=0;i<n;i++)
if(id_degree_cnt[id[i]]==0)
rel.add(i);
for(int d:rel)
out.print((d+1)+" ");
out.println();

}
out.flush();
out.close();
}
public static void dfsa(int ci)
{

for(int i=0;i<mapa[ci].size();i++)
{
int next=(Integer)mapa[ci].get(i);
if(vst[next]==false)
{
vst[next]=true;
dfsa(next);
}
}
order[tag++]=ci;
}
public static void dfst(int ci)
{
id[ci]=tag;
for(int i=0;i<mapt[ci].size();i++)
{
int next=(Integer)mapt[ci].get(i);
if(vst[next]==false)
{
vst[next]=true;
dfst(next);
}
}
}

}
2


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 笔记本电源已接通未充电怎么办 电源已接通未充电怎么办 遮盖纹身好了颜色淡了怎么办 致炫方向盘变重怎么办 xp音频图标没了怎么办 狙击精英3没子弹怎么办 干活干的手腕疼怎么办 干了活不给钱怎么办 干了活要不到钱怎么办 活干完了钱不给怎么办 微信语音聊天音量很小怎么办 一手软件崩溃钱卡住了怎么办 身上皮肤很黑怎么办?好想穿短裙 家里有很多小飞虫怎么办 家里有垃圾中飞出虫子怎么办 雷蛇笔记本很烫怎么办 登录监控器的账号锁了怎么办 悦借钱登录账号被锁怎么办 365账号登录被锁怎么办 台式电脑cpu温度过高怎么办 UG2.0打不开错误—15怎么办 键盘空格键删除键失灵怎么办 耳麦检测声音不分左右怎么办 吃生萝卜胃疼怎么办 幼兔拉稀怎么办没精神 自酿米酒酸了怎么办 用冰敷脸感觉红烫了怎么办 吃了海兔的内脏怎么办 吃了鱿鱼的吸盘怎么办 想开个烧烤店没学过怎么办 墨鱼汁弄衣服上怎么办 干鱿鱼泡开发黄怎么办 吃了芥末胃疼怎么办 手撕鱿鱼咸了怎么办 孕妇吃了点芥末怎么办 葡萄酒上面有一层白霉怎么办 手机一不小心把视频删了怎么办 柑橘7月份果实小怎么办 鹦鹉鱼身上有小白点怎么办 鹦鹉鱼身上烂了怎么办 红鹦鹉鱼变黑了怎么办