zoukankan      html  css  js  c++  java
  • NOIP模拟 Date

    题目描述

    小Y和小Z好不容易有机会相见啦,可是邪恶的小H却不想让他们相见。现在有一些城市,城市之间有双向路径相连,有路径相连的城市之间可以互相到达。小H可以任意选择一条路径,然后用他的邪恶力量污染这条路径,使得它不能被通行。虽然小Y和小Z在千辛万苦之后相遇了,但小Y非常害怕。她想让小Z告诉她,他们初始在哪些点对上,小H就可以选择一条路径污染使得他们不能相见。

    注意:如果有一对点之间初始的时候就不联通,也是满足条件的,需要输出这对点。这是因为本来不联通,那么删一条边,当然也不联通。

    输入格式

    第一行两个数字 N 和 M 。N 表示城市数,M 表示路径数。
    第二行到第 M+1 行,两个数 a 和 b。其中 1≤a,b≤N ,表示 a 和 b 之间有路径相连。

    输出格式

    输出一个整数,表示所求点对的数量

    样例数据 1

    输入  [复制]

    2 1
    1 2

    输出

    1

    备注

    【样例说明】

    点对(1,2)满足不能相见的条件。

    【数据范围】

    对 30% 的输入数据 :1≤N≤100,1≤M≤200
    对 100% 的输入数据 :1≤N≤20000,1≤M≤40000

    题目分析

    直接求不连通的不是很容易,考虑用总数减去联通的。剩下的就是裸的tarjan求无向图的双联通,联通块内所有点都可以互相联通,总数减去s * (s - 1) / 2即可。

    code

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 20005, M = 40005;
    
    int n, m;
    int ecnt = 1, adj[N], nxt[M << 1], go[M << 1];
    int scccnt, sccno[N];
    long long sccNum[N], ans;
    int low[N], dfn[N], clk;
    stack<int> S;
    
    inline void dfs(int u, int ee){
    	dfn[u] = low[u] = ++clk;
    	S.push(u);
    	
    	for(int e = adj[u]; e != -1; e = nxt[e]){
    		if(e == (ee ^ 1)) continue;
    		int v = go[e];
    		if(!dfn[v]){
    			dfs(v, e);
    			low[u] = min(low[u], low[v]);
    		}
    		else if(!sccno[v])
    			low[u] = min(low[u], dfn[v]); 
    	}
    	
    	if(low[u] == dfn[u]){
    		int x;
    		scccnt++;
    		for(;;){
    			x = S.top(); S.pop();
    			sccNum[scccnt]++;
    			sccno[x] = scccnt;
    			if(x == u) break;
    		}
    		ans -= sccNum[scccnt] * (sccNum[scccnt] - 1) / 2;
    	}
    }
    
    inline void addEdge(int u, int v){
    	nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v;
    	nxt[++ecnt] = adj[v], adj[v] = ecnt, go[ecnt] = u;
    }
    
    int main(){
    	ios::sync_with_stdio(false);
    	cin.tie(NULL), cout.tie(NULL);
    	cin >> n >> m;
    	memset(adj, -1, sizeof adj);
    	for(int i = 1; i <= m; i++){
    		int a, b; cin >> a >> b;
    		addEdge(a, b);
    	}
    	ans = n  * (n - 1) / 2;
    	for(int i = 1; i <= n; i++)
    		if(!dfn[i]) dfs(i, -1);
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    聊聊Flame Graph(火焰图)的那些事
    Dynamometer:HDFS性能扩展测试工具
    论分布式系统中单一锁控制的优化
    聊聊磁盘数据的损坏
    分级副本存储:一种更具效益成本的数据容错策略
    分布式存储系统中的Data Scrubbing机理
    论一个成熟分布式系统的工具类设计
    聊聊Raft一致性协议以及Apache Ratis
    ListenableFuture的状态同步和原子更新
    2018-9-1-win10-uwp-轻量级-MVVM-框架入门-2.1.5.3199
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7637748.html
Copyright © 2011-2022 走看看