• [bzoj1093][ZJOI2007]最大半连通子图


    题目大意:一个有向图称为半连通的,当且仅当对于任意两点$u,v$,都满足$u$能到达$v$或者$v$能到达$u$。给一张有向图,问该图最大半连通子图的节点个数及方案数。

    题解:发现任意一个强连通分量显然都是半连通子图。把它们都缩成一个点。形成一个$DAG$,问题就转化为了找最长链长度及方案数。$DP$即可

    卡点:方案数忘取模

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #define maxn 100010
    #define maxm 1000010
    
    #define ONLINEJUDGE
    #define read() R::READ()
    #include <cctype>
    namespace R {
        int x;
        #ifdef ONLINE_JUDGE
        char *ch, op[1 << 26];
        inline void init() {
            fread(ch = op, 1, 1 << 26, stdin);
        }
        inline int READ() {
            while (isspace(*ch)) ch++;
            for (x = *ch & 15, ch++; isdigit(*ch); ch++) x = x * 10 + (*ch & 15);
            return x;
        }
        #else
        char ch;
        inline int READ() {
            ch = getchar();
            while (isspace(ch)) ch = getchar();
            for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
            return x;
        }
        #endif
    }
    
    int n, m, mod, ans, num;
    inline void getans(int a, int b) {
    	if (ans == a) (num += b) %= mod;
    	if (ans < a) ans = a, num = b;
    }
    inline int min(int a, int b) {return a < b ? a : b;}
    
    namespace Tree {
    	int sz[maxn], ind[maxn], CNT;
    	
    	int head[maxn], cnt;
    	struct Edge {
    		int to, nxt;
    	} e[maxm];
    	void add(int a, int b) {
    		e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    		ind[b]++;
    	}
    	
    	int q[maxn], h = 1, t = 0;
    	int f[maxn], num[maxn];
    	void bfs() {
    		for (int i = 1; i <= CNT; i++) if (!ind[i]) {
    			q[++t] = i;
    			f[i] = sz[i];
    			num[i]++;
    			getans(f[i], num[i]);
    		}
    		while (h <= t) {
    			int u = q[h++];
    			for (int i = head[u]; i; i = e[i].nxt) {
    				int v = e[i].to;
    				if (f[v] < f[u] + sz[v]) {
    					f[v] = f[u] + sz[v];
    					num[v] = num[u];
    				} else if (f[v] == f[u] + sz[v]) (num[v] += num[u]) %= mod;
    				if (!--ind[v]) {
    					getans(f[v], num[v]);
    					q[++t] = v;
    				}
    			}
    		}
    	}
    }
    namespace Graph {
    	int res[maxn];
    	int head[maxn], cnt;
    	struct Edge {
    		int from, to, nxt;
    		inline bool operator < (const Edge &rhs) const{
    			if (res[from] == res[rhs.from]) return res[to] < res[rhs.to];
    			else return res[from] < res[rhs.from];
    		}
    	} e[maxm];
    	void add(int a, int b) {
    		e[++cnt] = (Edge) {a, b, head[a]}; head[a] = cnt;
    	}
    	
    	int DFN[maxn], low[maxn], idx;
    	int S[maxn], top;
    	bool ins[maxn];
    	void Tarjan(int u) {
    		DFN[u] = low[u] = ++idx;
    		ins[S[++top] = u] = true;
    		int v;
    		for (int i = head[u]; i; i = e[i].nxt) {
    			v = e[i].to;
    			if (!DFN[v]) {
    				Tarjan(v);
    				low[u] = min(low[u], low[v]);
    			} else if (ins[v]) low[u] = min(low[u], DFN[v]);
    		}
    		if (low[u] == DFN[u]) {
    			Tree::CNT++;
    			do {
    				ins[v = S[top--]] = false;
    				Tree::sz[res[v] = Tree::CNT]++;
    			} while (v != u); 
    		}
    	}
    	inline void tarjan(int n) {
    		for (int i = 1; i <= n; i++) if (!DFN[i]) Tarjan(i);
    	}
    	
    	void init() {
    		std::sort(e + 1, e + cnt + 1);
    		for (int i = 1; i <= cnt; i++) {
    			if (res[e[i].from] == res[e[i - 1].from] && res[e[i].to] == res[e[i - 1].to]) continue;
    			if (res[e[i].from] != res[e[i].to]) Tree::add(res[e[i].from], res[e[i].to]);
    		}
    	}
    }
    
    int main() {
        #ifdef ONLINE_JUDGE
        R::init();
        #endif
        n = read(), m = read(), mod = read();
    	for (int i = 1; i <= m; i++) {
    		int a = read(), b = read();
    		Graph::add(a, b);
    	}
    	Graph::tarjan(n);
    	Graph::init();
    	Tree::bfs();
    	printf("%d
    %d
    ", ans, num);
    	return 0;
    }
    
  • 相关阅读:
    数据结构 图的接口定义与实现分析(超详细注解)
    数据结构-优先队列 接口定义与实现分析
    什么是梯度?
    javascript当中火狐的firebug如何单步调试程序?
    给出一个javascript的Helloworld例子
    lvs dr 模型配置详解
    数据库连接池
    JDBC事务管理
    JDBC工具类:JDBCUtils
    详解JDBC对象
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9661530.html
Copyright © 2020-2023  润新知