zoukankan      html  css  js  c++  java
  • UVa 1108

    题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=3549&mosmsg=Submission+received+with+ID+26579033

    求出图中的所有双连通分量,如果整张图都是双连通分量,则任选两个点涂黑。

    否则枚举双连通分量,如果该分量中有一个割点,那么该分量要选一个点涂黑(不涂割点),否则无需涂该分量(因为总有另一个割点通往其他的分量)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 50010;
    
    int n, m;
    
    int h[maxn], cnt = 0;
    struct E{
    	int from, to, next;
    //	E(int from, int to, int next): from(from), to(to), next(next){}
    }e[maxn << 1];
    void add(int u, int v){
    	e[++cnt].to = v;
    	e[cnt].from = u;
    	e[cnt].next = h[u]; 
    	h[u] = cnt;
    }
    
    stack<E> s;
    vector<int> bcc[maxn];
    int st[maxn], low[maxn], iscut[maxn], bccno[maxn], dfn = 0, bcc_cnt = 0;
    
    int dfs(int u, int par){
    	low[u] = st[u] = ++dfn;
    	
    	int child = 0;
    	for(int i = h[u] ; i != -1 ; i = e[i].next){
    		int v = e[i].to;
    		E ee = (E){u, v, -1};
    		if(!st[v]){
    			s.push(ee);
    			++child;
    			low[v] = dfs(v, u);
    			low[u] = min(low[u], low[v]);
    			
    			if(low[v] >= st[u]){
    				iscut[u] = 1;
    				++bcc_cnt;
    				bcc[bcc_cnt].clear();
    				for(;;){
    					E x = s.top(); s.pop();
    					if(bccno[x.from] != bcc_cnt) { bcc[bcc_cnt].push_back(x.from); bccno[x.from] = bcc_cnt; }
    					if(bccno[x.to] != bcc_cnt) { bcc[bcc_cnt].push_back(x.to); bccno[x.to] = bcc_cnt; }
    					if(x.from == u && x.to == v) break;
    				}
    			}
    		} else if(st[v] < st[u] && v != par){
    			s.push(ee);
    			low[u] = min(low[u], st[v]);
    		}
    	}
    	
    	if(par == 0 && child == 1) iscut[u] = 0;
    	return low[u];
    }
    
    void tarjan(){
    	memset(st, 0, sizeof(st));
    	memset(iscut, 0, sizeof(iscut));
    	memset(low, 0, sizeof(low));	
    	memset(bccno, 0, sizeof(bccno));
    	dfn = 0; bcc_cnt = 0;
    	
    	for(int i = 1 ; i <= n ; ++i){
    		if(!st[i]){
    			dfs(1, 0);
    		}
    	}
    }
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	int kase = 0;
    	while(scanf("%d", &m) && m){
    		n = 0; 
    
    		memset(h, -1, sizeof(h)); cnt = 0;
    		
    		int u, v;
    		for(int i = 1 ; i <= m ; ++i){
    			scanf("%d%d", &u, &v);
    			add(u, v); add(v, u);
    			n = max(n, u); n = max(n, v);
    		}
    		
    		tarjan();
    		
    		int ans = 0; ll way = 0;
    		if(bcc_cnt == 1){
    			ans = 2;
    			way = 1ll * n * (n - 1) / 2;
    		} else{
    			way = 1ll;
    			for(int i = 1 ; i <= bcc_cnt ; ++i){
    				int tot = 0;
    				for(int j = 0 ; j < bcc[i].size() ; ++j){
    					if(iscut[bcc[i][j]]){
    						++tot;
    					}
    				}
    				if(tot == 1) {
    					++ans;
    					way = 1ll * way * (bcc[i].size() - 1);
    				}
    			}
    		}
    		printf("Case %d: %d %lld
    ", ++kase, ans, way);
    	}
    	return 0;
    }
    
  • 相关阅读:
    vscode 自动换行 关闭
    QGIS geojson 矢量操作 稀释 抽稀 压缩 边界抽稀
    vscode 关闭烦人的 tooltip 提示
    sql函数汉字转拼音
    sql 排名函数
    客户端文件下载 download.js
    Oracle 创建 DBLink 的方法
    RDLC分组序号
    sql server中使用函数验证身份证号码是否合法
    oracle导出数据库exp时报错,ORA12154 TNS: 无法解析指定的连接标识符
  • 原文地址:https://www.cnblogs.com/tuchen/p/15022399.html
Copyright © 2011-2022 走看看