UVAlive 6044 - Unique Path(边双连通分量)
2015-08-08 22:42
399 查看
题目:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85218#problem/G
思路:
贴上代码当模板
AC。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int maxn = 1e4+5;
const int maxm = 1e5+5;
int n, m;
int tot, head[maxn];
struct Edge {
int to, next;
bool cut;
}edge[maxm*2];
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int low[maxn], dfn[maxn], stck[maxn], belong[maxn];
int indx, top;
int block;
bool instack[maxn];
int bridge;
int dfs(int u, int pre)
{
int v;
low[u] = dfn[u] = ++indx;
stck[top++] = u;
instack[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next) {
v = edge[i].to;
if(v == pre) continue;
if(!dfn[v]) {
dfs(v, u);
if(low[u] > low[v]) low[u] = low[v];
if(low[v] > dfn[u]) {
bridge++;
edge[i].cut = true;
edge[i^1].cut = true;
}
}
else if(instack[v] && low[u] > dfn[v]) {
low[u] = dfn[v];
}
}
if(low[u] == dfn[u]) {
block++;
do {
v = stck[--top];
instack[v] = false;
belong[v] = block;
}while(v != u);
}
}
void solve()
{
memset(dfn, 0, sizeof(dfn));
memset(instack, 0, sizeof(instack));
memset(belong, 0, sizeof(belong));
indx = top = block = 0;
for(int i = 1; i <= n; ++i) {
if(!belong[i]) dfs(i, 0);
}
}
bool vis[maxn];
int dfs1(int u)
{
int num = 0;
vis[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(vis[v]) continue;
num += dfs1(v);
}
return num + 1;
}
int cnt[maxn];
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
}
int main()
{
//freopen("in", "r", stdin);
int T, ca = 1;
scanf("%d", &T);
while(T--) {
init();
scanf("%d %d", &n, &m);
int u, v;
for(int i = 0; i < m; ++i) {
scanf("%d %d", &u, &v);
addedge(u, v);
addedge(v, u);
}
solve();
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; ++i) {
cnt[belong[i]]++;
}
for(int i = 1; i <= n; ++i) {
if(cnt[belong[i]] > 1) vis[i] = 1;
}
int ans = 0;
for(int i = 1; i <= n; ++i) {
if(!vis[i]) {
int num = dfs1(i);
ans += (num*(num-1)) / 2;
}
}
printf("Case #%d: %d\n", ca++, ans);
}
return 0;
}
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85218#problem/G
思路:
贴上代码当模板
AC。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int maxn = 1e4+5;
const int maxm = 1e5+5;
int n, m;
int tot, head[maxn];
struct Edge {
int to, next;
bool cut;
}edge[maxm*2];
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int low[maxn], dfn[maxn], stck[maxn], belong[maxn];
int indx, top;
int block;
bool instack[maxn];
int bridge;
int dfs(int u, int pre)
{
int v;
low[u] = dfn[u] = ++indx;
stck[top++] = u;
instack[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next) {
v = edge[i].to;
if(v == pre) continue;
if(!dfn[v]) {
dfs(v, u);
if(low[u] > low[v]) low[u] = low[v];
if(low[v] > dfn[u]) {
bridge++;
edge[i].cut = true;
edge[i^1].cut = true;
}
}
else if(instack[v] && low[u] > dfn[v]) {
low[u] = dfn[v];
}
}
if(low[u] == dfn[u]) {
block++;
do {
v = stck[--top];
instack[v] = false;
belong[v] = block;
}while(v != u);
}
}
void solve()
{
memset(dfn, 0, sizeof(dfn));
memset(instack, 0, sizeof(instack));
memset(belong, 0, sizeof(belong));
indx = top = block = 0;
for(int i = 1; i <= n; ++i) {
if(!belong[i]) dfs(i, 0);
}
}
bool vis[maxn];
int dfs1(int u)
{
int num = 0;
vis[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(vis[v]) continue;
num += dfs1(v);
}
return num + 1;
}
int cnt[maxn];
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
}
int main()
{
//freopen("in", "r", stdin);
int T, ca = 1;
scanf("%d", &T);
while(T--) {
init();
scanf("%d %d", &n, &m);
int u, v;
for(int i = 0; i < m; ++i) {
scanf("%d %d", &u, &v);
addedge(u, v);
addedge(v, u);
}
solve();
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; ++i) {
cnt[belong[i]]++;
}
for(int i = 1; i <= n; ++i) {
if(cnt[belong[i]] > 1) vis[i] = 1;
}
int ans = 0;
for(int i = 1; i <= n; ++i) {
if(!vis[i]) {
int num = dfs1(i);
ans += (num*(num-1)) / 2;
}
}
printf("Case #%d: %d\n", ca++, ans);
}
return 0;
}
相关文章推荐
- 1.10055 - Hashmat the brave warrior
- 2.10071 - Back to High School Physics
- 3.458 - The Decoder
- 4.694 - The Collatz Sequence
- 6.494 - Kindergarten Counting Game
- 7.490 - Rotating Sentences
- 8.414 - Machined Surfaces
- 9.488 - Triangle Wave
- A.457 - Linear Cellular Automata
- B.489 - Hangman Judge
- C.445 - Marvelous Mazes
- 1.10494 - If We Were a Child Again
- 2.424 - Integer Inquiry
- 3.10250 - The Other Two Trees
- 5.465 - Overflow
- 6.113 - Power of Cryptography
- 7.10161 - Ant on a Chessboard
- 8.621 - Secret Research
- 9.401 - Palindromes
- A.537 - Artificial Intelligence?