题意:给一个无向图,你需要给所有边定向,使定向之后存在最多的点对$(a,b)$使得从$a$能到$b$

这个题,真的是太妙啦!

首先,给一个边双联通分量定向之后,它可以变成一个强联通分量,所以我们显然要把每个双联通分量缩点,然后处理树上的问题

那么答案分为两部分,一部分是双联通分量内部的,一个是树上的

设某双联通分量的大小为$k$,因为给它定向之后里面的点两两可以互达,所以它对答案的贡献为$k^2$

接下来找树上的,有一个结论说,最优解一定长这样:存在一个点$s$,使得对于任意其他点$t$,要么$s$可以到$t$,要么$t$可以到$s$,我们把$s$作为根使整棵树成为有根树

感觉上是对的没错我不会证

出题人这样说:

这种玄学的东西真是令人不知所措......

回归正题,有了这个结论,我们可以知道,$s$的每一个子树内的边要么都朝向$s$,要么都是远离$s$的方向

我们可以枚举根

记$s_i$为编号为$i$的双联通分量的大小,$siz_i$记以$i$为根的子树大小

那么每个节点$i$的子树内贡献的答案就是$s_i\cdot(siz_i-s_i)$

所以最后我们还得统计一下过根的答案,也就是决定连着根的那些边的朝向

假设朝向根的节点的$siz$总和为$p$,那么过根的答案就是$p\cdot(n-s_i-p)$

所以我们要做的就是把根的子树分成尽可能平均的两部分,直接上背包就好了

然后,终于做完了......

#include<stdio.h>
#include<string.h>
struct gedge{int to,nex;bool bri;
}ge[4000010];
struct tedge{int to,nex;
}te[4010];
int gh[2010],th[2010],s[2010],siz[2010],dfn[2010],low[2010],col[2010],q[2010],f[2010],tot,m;
void gadd(int a,int b){tot++;ge[tot].to=b;ge[tot].nex=gh[a];gh[a]=tot;ge[tot+m].to=a;ge[tot+m].nex=gh[b];gh[b]=tot+m;
}
void tadd(int a,int b){tot++;te[tot].to=b;te[tot].nex=th[a];th[a]=tot;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
void bri(int x){ge[x].bri=1;if(x>m)ge[x-m].bri=1;elsege[x+m].bri=1;
}
void tarjan(int fa,int x){tot++;dfn[x]=low[x]=tot;for(int i=gh[x];i;i=ge[i].nex){if(dfn[ge[i].to]==0){tarjan(x,ge[i].to);low[x]=min(low[x],low[ge[i].to]);if(low[ge[i].to]>dfn[x])bri(i);}else if(dfn[ge[i].to]<dfn[x]&&ge[i].to!=fa)low[x]=min(low[x],dfn[ge[i].to]);}
}
void dfs(int x){for(int i=gh[x];i;i=ge[i].nex){if(col[ge[i].to]){if(col[ge[i].to]!=col[x]){tadd(col[x],col[ge[i].to]);tadd(col[ge[i].to],col[x]);}}else if(!ge[i].bri){col[ge[i].to]=col[x];dfs(ge[i].to);}}
}
void dfs(int fa,int x){siz[x]=s[x];for(int i=th[x];i;i=te[i].nex){if(te[i].to!=fa){dfs(x,te[i].to);siz[x]+=siz[te[i].to];}}
}
int main(){int N,n,i,j,k,a,b,ans,res;scanf("%d%d",&n,&m);for(i=0;i<m;i++){scanf("%d%d",&a,&b);gadd(a,b);}tot=0;tarjan(0,1);N=0;tot=0;for(i=1;i<=n;i++){if(col[i]==0){N++;col[i]=N;dfs(i);}}for(i=1;i<=n;i++)s[col[i]]++;ans=0;for(i=1;i<=N;i++){dfs(0,i);res=0;for(j=1;j<=N;j++)res+=s[j]*siz[j];q[0]=0;for(j=th[i];j;j=te[j].nex){q[0]++;q[q[0]]=te[j].to;}memset(f,0,sizeof(f));for(j=1;j<=q[0];j++){for(k=n-s[i];k>=siz[q[j]];k--)f[k]=max(f[k],f[k-siz[q[j]]]+siz[q[j]]);}res+=f[(n-s[i])>>1]*(n-s[i]-f[(n-s[i])>>1]);ans=max(ans,res);}printf("%d",ans);
}

转载于:https://www.cnblogs.com/jefflyy/p/7905970.html

[CF475E]Strongly Connected City 2相关推荐

  1. CodeForces - 475B Strongly Connected City(最短路+判断强联通图/思维)

    题目链接:点击查看 题目大意:给出n和m然后给出n条横向街道和m条纵向街道,总共包括了n*m个结点,每条街道都是单向通道,问该图是否能够组成强联通图(有向图中任意两点间都存在路径) 题目分析:乍一看没 ...

  2. codeforces B. Strongly Connected City(dfs水过)

    题意:有横向和纵向的街道,每个街道只有一个方向,垂直的街道相交会产生一个节点,这样每个节点都有两个方向, 问是否每一个节点都可以由其他的节点到达.... 思路:规律没有想到,直接爆搜!每一个节点dfs ...

  3. HDU 4635 Strongly connected(缩点、最多可加边数使得仍然非强连通)

    整理的算法模板合集: ACM模板 HDU 4635 Strongly connected Give a simple directed graph with N nodes and M edges. ...

  4. 【CF913F】Strongly Connected Tournament 概率神题

    [CF913F]Strongly Connected Tournament 题意:有n个人进行如下锦标赛: 1.所有人都和所有其他的人进行一场比赛,其中标号为i的人打赢标号为j的人(i<j)的概 ...

  5. JavaScript实现strongly Connected Components 强连通分量算法(附完整源码)

    JavaScript实现strongly Connected Components 强连通分量算法(附完整源码) Comparator.js完整源代码 LinkedListNode.js完整源代码 L ...

  6. Strongly connected HDU - 4635(tarjan+强连通分量)

    题意: 给一个简单有向图,让你加最多的边,使他还是一个简单有向图. 题目: Give a simple directed graph with N nodes and M edges. Please ...

  7. 【HDU - 4635】Strongly connected(缩点,新图性质,建图,Tarjan求强连通分量)

    题干: Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the ...

  8. 数学 {连通性 `Connected`, 强连通性 `Strongly Connected`}

    数学 {连通性 Connected, 强连通性 Strongly Connected} 连通性 Connected 定义 设R是定义在X上的齐次二元关系, ( ∀ x 1 ≠ x 2 ∈ X , R ...

  9. 图论学习六之Strongly connected components强连通分量

    强连通分量(Strongly connected cmponents) • 在有向图G中,如果任意两个不同的顶点相互可达,则称该有向   图是强连通的.有向图G的极大强连通子图称为<

最新文章

  1. jni string 转换
  2. 深度学习可视化工具visdom使用
  3. 神经网络的分类准确率到底是一个什么物理量
  4. 使用HBase Client访问阿里云NoSQL数据库表格存储
  5. VSCode注册关联自定义类型文件
  6. ubuntu安装ruby、安装sass
  7. xdpyinfo命令找不到_无法使用命令 /usr/bin/xdpyinfo 自动检查显示器颜色。
  8. 【转】make makefile cmake qmake都是什么,有什么区别?
  9. Linux系统编程34:进程信号之可重入函数,volatile关键字的作用和SIGHLD
  10. 模糊滤镜_如何用 PS,为照片增加模糊与动感效果
  11. 完美世界国际版不用外挂多开的方法
  12. n2n(Pear-to-pear) 内网穿透
  13. 二元函数偏导数公式_偏导数计算公式大全
  14. 概率论 方差公式_概率论学习笔记(6)
  15. Python 自动获取 Bing 壁纸
  16. 沙尘暴天气空气净化器市场走俏
  17. 【论文笔记】ParamE模型学习
  18. vm fusion Linux系统克隆
  19. 今年408试题的难度,和往年相比如何?
  20. 服务器除尘网站,浪潮服务器除尘清洗

热门文章

  1. 5G技术标准制定已加速 所有炒作都将变成现实
  2. 怎么样实现左侧页面点击后右边页面显示内容
  3. 第三周项目5-数组作数据成员
  4. PsTools在***中的一点小应用
  5. 我们这旮都是黑社会[转]
  6. linux 8051 编译,[编译] 3、在Linux下搭建51单片机的开发烧写环境(makefile版)
  7. 创建spring配置
  8. Nginx server_name精确匹配配置
  9. Spring构造注入重载
  10. setHeadAndPropagate