zoukankan      html  css  js  c++  java
  • POJ 1236.Network of Schools (强连通)

    首先要强连通缩点,统计新的图的各点的出度和入度。

    第一问直接输出入度为0的点的个数

    第二问是要是新的图变成一个强连通图,那么每一个点至少要有一条出边和一条入边,输出出度和入度为0的点数大的那一个

    注意特判,输入已经是一个极大强连通图的情况,输出 1 0

    code

    /*
           无向图强连通的Garbow算法,思路与Tarjan算法相同,实现更直接,效率更好
           时间复杂度同样为O(n+m)
           思路:
           dfn记录访问顺序,st为访问栈,tem为辅助栈
           每次找到环时,将环中除顺序最靠前的点其他的点全出栈st
           tem中当前点之上(包括当前点)的所有点为一个强连通分量
    */
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int INF = 109;
    struct node {
    	int u, v, ne;
    } E[INF*INF];
    int head[INF], cnt;
    int dfn[INF], num[INF], sta[INF], Tops, tem[INF], Topt, scc;
    int n;
    void addedge (int u, int v) {
    	E[++cnt].u = u, E[cnt].v = v;
    	E[cnt].ne = head[u];
    	head[u] = cnt;
    }
    void dfs (int k, int t) {
    	sta[++Tops] = tem[++Topt] = k;
    	dfn[k] = ++t;
    	for (int i = head[k]; i != 0; i = E[i].ne) {
    		int v = E[i].v;
    		if (!dfn[v]) dfs (v, t);
    		else if (num[v] == 0)
    			while (dfn[sta[Tops]] > dfn[v]) Tops--;
    	}
    	if (sta[Tops] == k) {
    		Tops--, scc++;
    		do
    			num[tem[Topt]] = scc;
    		while (tem[Topt--] != k);
    	}
    }
    void Garbow (int n) {
    	memset (dfn, 0, sizeof dfn);
    	memset (num, 0, sizeof num);
    	Tops = Topt = scc = 0;
    	for (int i = 1; i <= n; i++)
    		if (!num[i]) dfs (i, 0);
    }
    void make() {
    	Garbow (n);
    	int degi[INF], dego[INF];
    	memset (degi, 0, sizeof degi);
    	memset (dego, 0, sizeof dego);
    	if (scc == 1) {
    		cout << 1 << endl << 0 << endl;
    		return ;
    	}
    	for (int i = 1; i <= cnt; i++) {
    		int u = E[i].u, v = E[i].v;
    		if (num[u] != num[v]) {
    			degi[num[v]] = 1;
    			dego[num[u]] = 1;
    		}
    	}
    	int ans1=0, ans2=0;
    	for (int i = 1; i <= scc; i++) {
    		if (degi[i] == 0) ans1++;
    		if (dego[i] == 0) ans2++;
    	}
    	cout << ans1 <<endl<< max (ans1, ans2);
    }
    int main() {
    	cin >> n;
    	for (int i = 1; i <= n; i++) {
    		int x;
    		while (cin >> x && x)
    			addedge (i, x);
    	}
    	make();
    	return 0;
    }
    

      

  • 相关阅读:
    Linux下搭建socks5代理
    在vs2005 使用FreeTextBox
    毕业了!!
    ASP.net 2.0上传图片方法
    再网页中,怎么用VS2005中的日历空件输入日期格式!
    毕业设计!!
    学校终于放假了,今天就可以回家了!
    求职!本人是07届刚毕业的学生!求程序员
    libcurl教程(转)
    spring boot集成swagger3
  • 原文地址:https://www.cnblogs.com/keam37/p/3956977.html
Copyright © 2011-2022 走看看