题目大意:
  给你一个有向图,你可以把其中某一条单向边改成双向边,使得图中最大的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. Python作业模拟登陆(第一周)

    模拟登陆:1. 用户输入帐号密码进行登陆2. 用户信息保存在文件内3. 用户密码输入错误三次后锁定用户 思路: 1. 用户名密码文件为passwd,锁定用户文件为lock 2. 用户输入账号密码采用i ...

  2. c语言中的输入

    先打个白条有时间在写 c语言中输入一行回车之后,以空格为单位进行的分割

  3. Laravel 项目登录报错:The MAC is invalid.

    在 Laravel 项目完成部署到服务器.数据库导入成功后 后台登录报错: 原因是 Laravel 的 APP_KEY 和 encrypt() 函数加密的问题.(encrypt() 是 Laravel ...

  4. python基础===新式类与经典类

    首先: Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,不必显式的继承object 这两种类的区别: 新式类重定义的方法更多,当然这不 ...

  5. 【模板】BZOJ 3781: 小B的询问 莫队算法

    http://www.lydsy.com/JudgeOnline/problem.php?id=3781 N个数的序列,每次询问区间中每种数字出现次数的平方和,可以离线. 丢模板: #include ...

  6. Atom:优雅迷人的编辑神器

    对于热爱markdown写作的人来说,Atom同样是一款拥有无穷魅力的写作软件.我不怕它无法满足你的需求,就怕你不给一个机会了解它,那么,这将是一场遗憾的错过. 大学的时候,坊间对那些编程高手有一个令 ...

  7. FineReport——巧妙实现类tab布局

    在FR中,表达form支持局部刷新和tab布局,在报表中,不能做到这样,只能舍弃一些功能来做到类似的tab布局. 首先,在参数面板放一个文本控件temp,用作一个临时值,需要设置一个默认值,而切换是通 ...

  8. maven项目的多级目录

    刚刚把一个开源的项目变成maven项目来进行管理,由于是多级的目录(以前配置的都是单级的目录),所以记录一下pom文件是怎么配置的. 一.目录结构 如下,maven的结构图,红字是表示完整的项目

  9. Leetcode 之Length of Last Word(37)

    扫描每个WORD的长度并记录即可. int lengthOfLast(const char *s) { //扫描统计每个word的长度 ; while (*s) { if (*s++ != ' ')/ ...

  10. python读写xml文件

    python读取xml文件 xml文件是具有树状结构的,如果想要访问某个叶子结点,必须逐层获取其父结点,要读取某个叶子结点内容用text成员 使用前先加载xml工具包 try: import xml. ...