[CC-LONCYC]Lonely Cycles

题目大意:

\(T(T\le1000)\)组数据。

给定一张简单图(不含重边与自环),图中有\(n(n\le2\times10^5)\)个节点和\(m(\sum n+m\le5\times10^6)\)条边。每个节点最多属于一个简单环。

对于每条边,求出有多少简单路径包含这条边且至多包含一条在简单环上的边。

思路:

缩点后根据是否为环上边讨论,环上边的方案数就是两边结点数之积。去掉这些环就只剩下若干棵树,可以树形DP。

源代码:

#include<stack>
#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=2e5+1,M=5e6;
struct Edge2 {
int u,v,id;
};
Edge2 edge[M];
struct Edge {
int to,id;
};
std::vector<Edge> e[N];
inline void add_edge(const int &u,const int &v,const int &id) {
e[u].push_back((Edge){v,id});
e[v].push_back((Edge){u,id});
}
bool ins[N],vis[N];
std::stack<int> s;
int dfn[N],low[N],scc[N],size[N],top[N],par[N],sum[N];
int64 ans[M];
void tarjan(const int &x,const int &par) {
s.push(x);
ins[x]=true;
dfn[x]=low[x]=++dfn[0];
for(auto &j:e[x]) {
const int &y=j.to;
if(y==par) continue;
if(!dfn[y]) {
tarjan(y,x);
low[x]=std::min(low[x],low[y]);
} else if(ins[y]) {
low[x]=std::min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]) {
scc[0]++;
int y;
do {
y=s.top();
s.pop();
ins[y]=false;
scc[y]=scc[0];
} while(y!=x);
}
}
void dfs(const int &x,const int &par) {
::par[x]=par;
size[x]=vis[x]=1;
top[x]=par?top[par]:x;
for(auto &j:e[x]) {
const int &y=j.to;
if(y==par||scc[x]==scc[y]) continue;
dfs(y,x);
size[x]+=size[y];
}
}
void dp1(const int &x) {
for(auto &j:e[x]) {
const int &y=j.to;
if(y==par[x]||top[x]!=top[y]) continue;
dp1(y);
sum[x]+=sum[y];
}
}
void dp2(const int &x) {
for(auto &j:e[x]) {
const int &y=j.to,&id=j.id;
if(y==par[x]||top[x]!=top[y]) continue;
dp2(y);
ans[id]+=(int64)(size[top[x]]-size[y])*size[y];
ans[id]+=(int64)(sum[top[x]]-sum[y])*size[y];
ans[id]+=(int64)sum[y]*(size[top[x]]-size[y]);
}
}
int main() {
for(register int T=getint();T;T--) {
const int n=getint(),m=getint();
for(register int i=0;i<m;i++) {
edge[i].u=getint();
edge[i].v=getint();
edge[i].id=i;
add_edge(edge[i].u,edge[i].v,i);
}
for(register int i=1;i<=n;i++) {
if(!dfn[i]) tarjan(i,0);
}
for(register int i=1;i<=n;i++) {
if(!vis[i]) dfs(i,0);
}
for(register int i=0;i<m;i++) {
const int &u=edge[i].u,&v=edge[i].v;
if(scc[u]!=scc[v]) continue;
ans[i]=(int64)size[top[u]]*size[top[v]];
sum[u]+=size[top[v]];
sum[v]+=size[top[u]];
}
for(register int i=1;i<=n;i++) {
if(i==top[i]) dp1(i);
}
for(register int i=1;i<=n;i++) {
if(i==top[i]) dp2(i);
}
for(register int i=0;i<m;i++) {
printf("%lld\n",ans[i]);
}
//Reset
for(register int i=1;i<=n;i++) {
e[i].clear();
}
std::fill(&sum[1],&sum[n]+1,0);
std::fill(&dfn[0],&dfn[n]+1,0);
std::fill(&ans[0],&ans[m],0);
std::fill(&vis[1],&vis[n]+1,false);
scc[0]=0;
}
return 0;
}

[CC-LONCYC]Lonely Cycles的更多相关文章

  1. Codechef August Challenge 2018 : Lonely Cycles

    传送门 几波树形dp就行了. #include<cstdio> #include<cstring> #include<algorithm> #define MN 5 ...

  2. Atitti.dw cc 2015 绿色版本安装总结

    Atitti.dw cc 2015 绿色版本安装总结 1.1. 安装程序无法初始化.请下载adobe Support Advisor检测该问题.1 1.1.1. Adobe Application M ...

  3. 【Hello CC.NET】CC.NET 实现自动化集成

    一.背景 公司的某一金融项目包含 12 个子系统,新需求一般按分支来开发,测完后合并到主干发布.开发团队需要同时维护开发环境.测试环境.模拟环境(主干).目前面临最大的两个问题: 1.子系统太多,每次 ...

  4. 浅谈iptables防SYN Flood攻击和CC攻击

    ------------------------本文为自己实践所总结,概念性的东西不全,这里粗劣提下而已,网上很多,本文主要说下目前较流行的syn洪水攻击和cc攻击------------------ ...

  5. checking for fcc ....no checking for cc .. no

         源码编译,提示缺少gcc cc cl.exe 解决方案:       yum install -y gcc glibc

  6. 编译器 cc、gcc、g++、CC 的区别

    gcc 是GNU Compiler Collection,原名为Gun C语言编译器,因为它原本只能处理C语言,但gcc很快地扩展,包含很多编译器(C.C++.Objective-C.Ada.Fort ...

  7. [CC]区域生长算法——点云分割

    基于CC写的插件,利用PCL中算法实现: void qLxPluginPCL::doRegionGrowing() { assert(m_app); if (!m_app) return; const ...

  8. [CC]点云密度计算

    包括两种计算方法:精确计算和近似计算(思考:local density=单位面积的点数 vs  local density =1/单个点所占的面积) 每种方法可以实现三种模式的点云密度计算,CC里面的 ...

  9. 【日常小记】统计后缀名为.cc、.c、.h的文件数【转】

    转自:http://www.cnblogs.com/skynet/archive/2011/03/29/1998970.html 在项目开发时,有时候想知道源码文件中有多少后缀名为.cc..c..h的 ...

随机推荐

  1. KVM -> 虚拟机磁盘管理_03

    1.KVM磁盘管理 1.KVM qcow2.raw.vmdk等镜像格式说明:http://blog.csdn.net/zhengmx100/article/details/53887162 raw: ...

  2. centos6.5环境自动化运维之puppet实现nginx反向代理功能及puppet安装配置详解

    puppet是一种Linux.Unix.windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件.用户.cron任务.软件包.系统服务等.puppet把这些系统实体称之为资 ...

  3. PL/SQL第四章 where子语句

    -- 学习where语句 -- 1.学会where子句中使用常规比较符 -- 常规比较操作符:=,<>(不等于),!=,>=,<=,>,< -- 当区分大小写时,可 ...

  4. Web Services基础学习(W3C)

    1.Web services 使用 XML 来编解码数据,并使用 SOAP 来传输数据 2.基础的 Web Services 平台是 XML + HTTP. Web services 平台的元素: S ...

  5. Android天气预报

    Android天气预报 1.指定 WebService 的命名空间和调用方法import org.ksoap2.serialization.SoapObject;private static fina ...

  6. 在vue-cli中引用公共过滤器filter

    在实际项目开发中,在某一组件中声明的全局过滤器Vue.filter并不能在其他组件中使用,所以,我认为只要调用两次以上或者可能会被调用两次以上的过滤器,就应该写入统一个过滤器文件中,方便统一调用.下面 ...

  7. php反射类的使用及Laravel对反射的使用介绍

    PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法.成员,而反射类则是拆封类中的所有方法.成员变量,并包括私有方法等.就如“解刨”一样,我们可以调用任何关键字修饰的方法.成员.当然在正常业 ...

  8. Python中的各种转义符\n\r\t

    转义符 描述 \ 续行符(在行尾时) \\ 反斜杠符号 ' 单引号 " 双引号 \a 响铃 \b 退格(Backspace) \e 转义 \000 空 \n 换行 \v 纵向制表符 \t 横 ...

  9. python 全栈开发,Day142(flask标准目录结构, flask使用SQLAlchemy,flask离线脚本,flask多app应用,flask-script,flask-migrate,pipreqs)

    昨日内容回顾 1. 简述flask上下文管理 - threading.local - 偏函数 - 栈 2. 原生SQL和ORM有什么优缺点? 开发效率: ORM > 原生SQL 执行效率: 原生 ...

  10. python 全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)

    昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...