博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15) C - Cactus Jubilee
阅读量:5337 次
发布时间:2019-06-15

本文共 2603 字,大约阅读时间需要 8 分钟。

思路:

1.如果删掉的是桥,那么将图分成两个部分,设它们的大小分别为a和b,我们为了保证图的连通性,只能连两个部分之间的边,即a*b-1种可能

2.如果删掉的不是桥,那么就是简单环上的边,删掉后环变成了小树,而且我们只能连小树上的点之间的边,否则就会出现一条边在两个简单环中状况,

就不是仙人掌图了(画画图就知道了)。一颗大小为x的小树的贡献是x*(x-1)/2-(x-1),我们可以先把所有小树的贡献和算出来,然后对于每个简单环单独处理,

对于某个简单环我们减去以环上每个点为根的小树的贡献,然后加上断环后形成的新树的贡献就可以知道对于这个环上每条边删掉后的贡献了。

具体实现就是用点双联通求简单环,把桥用并查集连接起来形成小树。

代码:

#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC optimize(4)#include
using namespace std;#define y1 y11#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb emplace_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair
#define pli pair
#define pii pair
#define piii pair
#define pdd pair
#define mem(a, b) memset(a, b, sizeof(a))#define debug(x) cerr << #x << " = " << x << "\n";#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//headconst int N = 1e5 + 5;vector
g[N];vector
> bcc[N];int low[N], dfn[N], sz[N], cc[N], tot = 0, top = 0, cnt = 0, n, m;pair
stk[N];int fa[N];int Find(int x) { if(x == fa[x]) return x; else return fa[x] = Find(fa[x]);}void Merge(int x, int y) { x = Find(x); y = Find(y); if(x == y) return ; fa[x] = y; cc[y] += cc[x];}LL ans, sum;void tarjan(int u, int fa) { low[u] = dfn[u] = ++tot; sz[u] = 1; for (int v : g[u]) { pair
e = {u, v}; if(!dfn[v]) { stk[++top] = e; tarjan(v, u); sz[u] += sz[v]; low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) ans += sz[v]*1LL*(n-sz[v])-1; if(low[v] >= dfn[u]) { cnt++; while(stk[top] != e) { bcc[cnt].push_back(stk[top--]); } bcc[cnt].push_back(stk[top--]); } } else if(v != fa ) { if(dfn[v] < dfn[u]) stk[++top] = e, low[u] = min(low[u], dfn[v]); } }}int u, v, k;int main() { freopen("cactus.in", "r", stdin); freopen("cactus.out", "w", stdout); scanf("%d %d", &n, &m); while(m--) { scanf("%d %d", &k, &v); k--; while(k--) { scanf("%d", &u); g[u].pb(v); g[v].pb(u); v = u; } } tarjan(1, 1); for (int i = 1; i <= n; ++i) fa[i] = i, cc[i] = 1; for (int i = 1; i <= cnt; ++i) if(bcc[i].size() == 1) Merge(bcc[i][0].fi, bcc[i][0].se); for (int i = 1; i <= n; ++i) if(fa[i] == i) sum += cc[i]*1LL*(cc[i]-1)/2-(cc[i]-1); for (int i = 1; i <= cnt; ++i) { if(bcc[i].size() == 1) continue; LL tmp = sum, tot = 0; for (int j = 0; j < bcc[i].size(); ++j) { int u = bcc[i][j].fi; u = Find(u); tmp -= cc[u]*1LL*(cc[u]-1)/2-(cc[u]-1); tot += cc[u]; } ans += (tmp+tot*1LL*(tot-1)/2-(tot-1)-1)*1LL*bcc[i].size(); } printf("%lld\n", ans); return 0;}

 

转载于:https://www.cnblogs.com/widsom/p/11153330.html

你可能感兴趣的文章
BZOJ 1925: [Sdoi2010]地精部落( dp )
查看>>
c++中的string常用函数用法总结!
查看>>
界面交互之支付宝生活圈pk微信朋友圈
查看>>
[DLX精确覆盖+打表] hdu 2518 Dominoes
查看>>
SuperMap iServerJava 6R扩展领域开发及压力测试---判断点在那个面内(1)
查看>>
Week03-面向对象入门
查看>>
一个控制台程序,模拟机器人对话
查看>>
web.xml 中加载顺序
查看>>
pycharm激活地址
查看>>
hdu 1207 四柱汉诺塔
查看>>
Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
查看>>
display:none与visible:hidden的区别
查看>>
我的PHP学习之路
查看>>
【题解】luogu p2340 奶牛会展
查看>>
对PostgreSQL的 SPI_prepare 的理解。
查看>>
解决响应式布局下兼容性的问题
查看>>
京东静态网页练习记录
查看>>
使用DBCP连接池对连接进行管理
查看>>
【洛谷】【堆+模拟】P2278 操作系统
查看>>
hdu3307 欧拉函数
查看>>