首先求出SCC,把图缩点成一个DAG。

通过拓扑排序+DP求出:

dp0[x]:从x点出发能到的点的集合。

dp1[x]:能到x的点的集合。

对于一条边x->y,将它改为双向边后,形成的新的SCC的点数为dp0[x]&dp1[y]中1的个数,用bitset维护。

时间复杂度$O(\frac{n^3}{32})$。

#include<cstdio>
#include<bitset>
using namespace std;
const int N=2002,M=N*N;
int n,m,i,j,x,y,v[N],q[M],h,t,d[N],f[N],ans,res[M];
int g[N][N];bool G[N][N],vis[M];
bitset<N>dp0[N],dp1[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
void dfs1(int x){
v[x]=1;
for(int i=1;i<=n;i++)if(g[x][i]&&!v[i])dfs1(i);
q[++t]=x;
}
void dfs2(int x,int y){
v[x]=0,f[x]=y;dp0[y][x]=dp1[y][x]=1;
for(int i=1;i<=n;i++)if(g[i][x]&&v[i])dfs2(i,y);
}
int main(){
read(n),read(m);
for(i=1;i<=m;i++)read(x),read(y),g[x][y]=i;
for(i=1;i<=n;i++)if(!v[i])dfs1(i);
for(i=n;i;i--)if(v[q[i]])dfs2(q[i],q[i]);
for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(g[i][j]&&f[i]!=f[j])if(!G[f[i]][f[j]])G[f[i]][f[j]]=1,d[f[j]]++;
for(i=h=1,t=0;i<=n;i++)if(f[i]==i&&!d[i])q[++t]=i;
while(h<=t)for(x=q[h++],i=1;i<=n;i++)if(G[x][i]){
dp1[i]|=dp1[x];
if(!(--d[i]))q[++t]=i;
}
for(i=t;i;i--)for(x=q[i],j=1;j<=n;j++)if(G[j][x])dp0[j]|=dp0[x];
for(t=0,i=1;i<=n;i++)for(j=1;j<=n;j++)if(g[i][j]){
int now=(dp0[f[i]]&dp1[f[j]]).count();
if(now<2)continue;
if(now>ans)ans=now,q[t=1]=g[i][j];else if(now==ans)q[++t]=g[i][j];
}
printf("%d\n%d\n",ans,t);
for(i=1;i<=t;i++)vis[q[i]]=1;
for(t=0,i=1;i<=m;i++)if(vis[i])res[++t]=i;
if(t)for(printf("%d",res[1]),i=2;i<=t;i++)printf(" %d",res[i]);
return 0;
}

  

BZOJ4304 : 道路改建的更多相关文章

  1. [BZOJ4304]/[JZOJ3486]道路改建

    题目大意: 给你一个有向图,你可以把其中某一条单向边改成双向边,使得图中最大的SCC最大. 问SCC最大能是多少,有哪些方案? 思路: 对原图缩点后就变成了一个DAG. 我们在DAG上DP,记录一下从 ...

  2. PTA 08-图7 公路村村通 (30分)

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道 ...

  3. PAT 7-14 公路村村通

    https://pintia.cn/problem-sets/1111189748004499456/problems/1111189831248850957 现有村落间道路的统计数据表中,列出了有可 ...

  4. PTA 畅通工程之最低成本建设问题(30 分)(最小生成树 krusal)

    畅通工程之最低成本建设问题(30 分) 某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路 ...

  5. pta08-图7 公路村村通 (30分)

    08-图7 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...

  6. pat06-图6. 公路村村通(30)

    06-图6. 公路村村通(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. 7-6 公路村村通(30 分) 【prime】

    7-6 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤10 ...

  9. DS博客作业06--图

    1.本周学习总结 1.1.思维导图 1.2.谈谈你对图结构的认识及学习体会 本章学习了图结构的相关知识,图形结构属于复杂的非线性数据结构,在实际应用中很多问题可以用图来描述.在图结构中,每个元素可以有 ...

随机推荐

  1. [BZOJ3786]星系探索

    [BZOJ3786]星系探索 试题描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个 ...

  2. nginx(五)nginx与php的安装配置

    经过前面学习,对nginx有个大概的了解,来配置LNMP;只要是在系统安装过程中选择安装比较齐全的包,基本上系统都能满足安装要求,下面是我一个一个测试的,基本上全部安装所需的库文件,放心安装: [ro ...

  3. poj1125最短路

    Stockbroker Grapevine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30408   Accepted: ...

  4. Linux 面试题总结

    一. 填空题1. 在Linux系统中,以 (文件) 方式访问设备 .2. Linux内核引导时,从文件 (/etc/fstab) 中读取要加载的文件系统.3. Linux文件系统中每个文件用 (索引节 ...

  5. 【云计算】K8S DaemonSet 每个node上都运行一个pod

    Kubernetes容器集群中的日志系统集成实践 Kubernetes是原生的容器编排管理系统,对于负载均衡.服务发现.高可用.滚动升级.自动伸缩等容器云平台的功能要求有原生支持.今天我分享一下我们在 ...

  6. Redis windows安装配置与Jedis访问数据库

    一 Redis概要 Redis是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.它通常被称为数据结构服务器 ...

  7. 【转】MySQL Temporary Table相关问题的探究

    本文转载自:http://itindex.net/detail/10901-mysql-temporary-table 问题的引入 让我们先来观察几条非常简单的MySQL语句: mysql> c ...

  8. 【JAVA、C++】LeetCode 009 Palindrome Number

    Determine whether an integer is a palindrome. Do this without extra space. 解题思路一: 双指针法,逐位判断 Java代码如下 ...

  9. Light OJ 1393 Crazy Calendar (尼姆博弈)

    C - Crazy Calendar Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Su ...

  10. MFC中挂起线程和恢复线程

    DWORD SuspendThread ( HANDLE hThread );   //挂起线程DWORD ResumeThread ( HANDLE hThread );   //恢复线程 比如说我 ...