zoukankan      html  css  js  c++  java
  • [CF1045C]Hyperspace Highways

    题目大意:给一张$n$个点$m$条边的图,保证若有一个环,一定是完全子图,多次询问两个点之间的最短路径长度

    题解:把完全子图缩成一个点,圆方树,方点权值设成$1$,圆点设成$0$即可。

    卡点:数组开小

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #define maxn 100010
    #define maxm 500010
    inline int min(int a, int b) {return a < b ? a : b;}
    inline int max(int a, int b) {return a > b ? a : b;}
    
    namespace Tree {
    	int head[maxn << 1], cnt;
    	struct Edge {
    		int to, nxt;
    	} e[maxn << 2];
    	inline void addE(int a, int b) {
    		e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    		e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt;
    	}
    	
    	#define M 19
    	int nodenum, n;
    	int dep[maxn << 1], sum[maxn << 1], fa[M][maxn << 1];
    	void dfs(int u) {
    		for (int i = 1; i < M; i++) fa[i][u] = fa[i - 1][fa[i - 1][u]];
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			if (v != fa[0][u]) {
    				fa[0][v] = u; dep[v] = dep[u] + 1;
    				sum[v] = sum[u] + (v > n);
    				dfs(v);
    			}
    		}
    	}
    	inline int LCA(int x, int y) {
    		if (x == y) return x;
    		if (dep[x] < dep[y]) std::swap(x, y);
    		for (int i = dep[x] - dep[y]; i; i &= i - 1) x = fa[__builtin_ctz(i)][x];
    		if (x == y) return x;
    		for (int i = M - 1; ~i; i--) if (fa[i][x] != fa[i][y]) x = fa[i][x], y = fa[i][y];
    		return fa[0][x];
    	}
    	inline int ask(int x, int y) {
    		int lca = LCA(x, y);
    		return sum[x] + sum[y] - (sum[lca] << 1) + (lca > n);
    	}
    	void init(int __n) {
    		n = __n;
    		sum[1] = 0;
    		dfs(1);
    	}
    	#undef M
    }
    
    namespace Graph {
    	int head[maxn], cnt;
    	struct Edge {
    		int to, nxt;
    	} e[maxm << 1];
    	inline void addE(int a, int b) {
    		e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    		e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt;
    	}
    	
    	using Tree::nodenum;
    	int DFN[maxn], low[maxn], idx;
    	int S[maxn], top;
    	void tarjan(int u) {
    		DFN[u] = low[u] = ++idx;
    		S[++top] = u;
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			if (!DFN[v]) {
    				tarjan(v);
    				low[u] = min(low[u], low[v]);
    				if (low[v] >= DFN[u]) {
    					nodenum++;
    					Tree::addE(nodenum, u);
    					do {
    						v = S[top--];
    						Tree::addE(nodenum, v);
    					} while (v != e[i].to);
    				}
    			} else low[u] = min(low[u], DFN[v]);
    		}
    	}
    	void init(int n) {
    		tarjan(1);
    		Tree::init(n);
    	}
    }
    
    int n, m, Q;
    int main() {
    	scanf("%d%d%d", &n, &m, &Q); Tree::nodenum = Tree::n = n;
    	for (int i = 0, a, b; i < m; i++) {
    		scanf("%d%d", &a, &b);
    		Graph::addE(a, b);
    	}
    	Graph::init(n);
    	while (Q --> 0) {
    		int u, v;
    		scanf("%d%d", &u, &v);
    		printf("%d
    ", Tree::ask(u, v));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    VMware下桥接设置
    Silverlight 样式的灵活使用
    Silverlight网页打开后马上崩溃,“白屏”,而且毫无提示
    Silverlight中字典的使用
    WEBGIS网页崩溃问题分析
    MDB数据类型注意事项
    使用浏览器开发着工具查看地图或影响的请求信息
    ArcGIS出图调整
    启动aspx文件错误
    hdu3555(数位DP dfs/递推)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9777914.html
Copyright © 2011-2022 走看看