UVALive - 5135 Mining Your Own Business
2013-09-23 22:58
423 查看
刘汝佳白书上面的一道题目:题意是给定一个联通分量,求出割顶以及双连通分量的个数,并且要求出安放安全井的种类数,也就是每个双连通分量中结点数(除开 割顶)个数相乘,对于有2个及以上割顶的双连通分量可以不用安放安全井。如果整个图就是一个双连通分量,那么需要安放两个安全井,种类数是n*(n-1)/2.
代码来自刘汝佳白书:
View Code
代码来自刘汝佳白书:
#include <iostream> #include <sstream> #include <cstdio> #include <climits> #include <cstring> #include <cstdlib> #include <string> #include <stack> #include <map> #include <cmath> #include <vector> #include <queue> #include <algorithm> #define esp 1e-6 #define pi acos(-1.0) #define pb push_back #define mp(a, b) make_pair((a), (b)) #define in freopen("in.txt", "r", stdin); #define out freopen("out.txt", "w", stdout); #define print(a) printf("%d\n",(a)); #define bug puts("********))))))"); #define stop system("pause"); #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) #define inf 0x0f0f0f0f #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int, int> pii; typedef vector<pii,int> VII; typedef vector<int>:: iterator IT; const int maxn = 50000 + 10; int pre[maxn], low[maxn], iscut[maxn], dfs_clock; VI g[maxn], cut; int n; LL ans1, ans2, cut_cnt; int dfs(int u, int fa) { int lowu = pre[u] = ++dfs_clock; int child = 0; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(!pre[v]) { child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv >= pre[u]) { iscut[u] = 1; } } else if(pre[v] < pre[u] && v != fa) { lowu = min(lowu, pre[v]); } } if(child == 1 && fa < 0) iscut[u] = 0; return low[u] = lowu; } void find_bcc(int n) { memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); dfs_clock = 0; for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1); } int cnt; void dfs1(int u) { cnt++; pre[u] = 1; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(!pre[v]) { if(iscut[v]) cut_cnt++, cnt++, pre[v] = 1, cut.pb(v); else dfs1(v); } } } void solve(int n) { cut.clear(); cut_cnt= 0; memset(pre, 0, sizeof(pre)); for(int i = 0; i < n; i++) if(iscut[i]) cut_cnt++; if(cut_cnt == 0) ans1 = 2, ans2 = (LL)n*(n-1)/2; else for(int i = 0; i < n; i++) if(!pre[i] && !iscut[i]) { cut_cnt = cnt = 0; dfs1(i); for(int i = 0; i < cut.size(); i++) pre[cut[i]] = 0; cut.clear(); if(cut_cnt == 1) ans1++, ans2 *= (LL)(cnt-1); } } int main(void) { int m, t = 1; while(scanf("%d", &m), m) { n = 0; ans1 = 0, ans2 = 1; for(int i = 0; i < maxn; i++) g[i].clear(); while(m--) { int u, v; scanf("%d%d", &u, &v); n = max(n, max(u, v)); u--, v--; g[u].pb(v); g[v].pb(u); } find_bcc(n); solve(n); printf("Case %d: %I64d %I64d\n", t, ans1, ans2); t++; } return 0; }
View Code
相关文章推荐
- bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)
- UVALive - 5135 Mining Your Own Business(【无向图双连通分量】+【超级思维】)
- UVALive 5135 Mining Your Own Business 双连通分量
- UVAlive5135_Mining Your Own Business
- 【UVALive】5135 Mining Your Own Business 点双连通+割顶
- UVALive 5135 HDU 3844 Mining Your Own Business
- UVALive - 5135 Mining Your Own Business
- UVAlive 5135 Mining Your Own Business [点双连通分量] [求割顶]
- UVALive - 5135 Mining Your Own Business(双联通分量)
- UVALive5135 [Mining Your Own Business] tarjan求无向图双联通分量
- UVALive - 5135 Mining Your Own Business(双连通分量)
- UVALive 5135 - Mining Your Own Business(点双连通)
- UVALive 5135 Mining Your Own Business(BCC、割顶)
- UVALive 5135 Mining Your Own Business(点双连通分量)
- bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)
- UVALive - 5135 Mining Your Own Business 双连通分量
- UVALive-5135 Mining Your Own Business (无向图的双连通分量)
- Mining Your Own Business UVALive - 5135
- uvalive 5135 Mining Your Own Business(双连通分量)
- UVALive - 5135 Mining Your Own Business(双连通分量)