[BZOJ4304]/[JZOJ3486]道路改建
题目大意:
给你一个有向图,你可以把其中某一条单向边改成双向边,使得图中最大的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]道路改建的更多相关文章
- BZOJ4304 : 道路改建
首先求出SCC,把图缩点成一个DAG. 通过拓扑排序+DP求出: dp0[x]:从x点出发能到的点的集合. dp1[x]:能到x的点的集合. 对于一条边x->y,将它改为双向边后,形成的新的SC ...
- PTA 08-图7 公路村村通 (30分)
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道 ...
- PAT 7-14 公路村村通
https://pintia.cn/problem-sets/1111189748004499456/problems/1111189831248850957 现有村落间道路的统计数据表中,列出了有可 ...
- PTA 畅通工程之最低成本建设问题(30 分)(最小生成树 krusal)
畅通工程之最低成本建设问题(30 分) 某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路 ...
- pta08-图7 公路村村通 (30分)
08-图7 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...
- pat06-图6. 公路村村通(30)
06-图6. 公路村村通(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 7-6 公路村村通(30 分) 【prime】
7-6 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤10 ...
- DS博客作业06--图
1.本周学习总结 1.1.思维导图 1.2.谈谈你对图结构的认识及学习体会 本章学习了图结构的相关知识,图形结构属于复杂的非线性数据结构,在实际应用中很多问题可以用图来描述.在图结构中,每个元素可以有 ...
随机推荐
- canvas_简单练习
效果图 实现原理: 1.定义canvas标签. 2.获取canvas标签节点,创建canvas2D. 3.在canvas进行画图. 效果代码: <!DOCTYPE html> <ht ...
- this指针再解
this.new.call和apply的相关问题 讲解this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,因此本篇打算换一 ...
- hdu 1087 Super Jumping! Jumping! Jumping!(动态规划DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1087 Super Jumping! Jumping! Jumping! Time Limit: 200 ...
- RecycleView Bug:java.lang.IndexOutOfBoundsException: Inconsistency detected.
今天使用RecyclerView时,上下两个RecyclerView,在实现下拉刷新时,报错: java.lang.IndexOutOfBoundsException: Inconsistency d ...
- springcloud基于ribbon的canary路由方案
思路 根据eureka的metadata进行自定义元数据,然后使用ribbon对该元数据进行过滤和匹配,选择server. 实现 这里使用header来传递路由信息,改造ribbon-discover ...
- 使用yo -v查看yeoman版本号
使用yo -v无法查看yeoman版本,这是旧版本的方法 新版本使用yo --version即可查看
- mysql中的时间year/date/time/datetime
year: mysql> create table y(y year); Query OK, 0 rows affected (0.03 sec) mysql> desc y; +---- ...
- tornado简单使用
这篇适用于快速上手想了解更深:http://www.tornadoweb.cn/ https://tornado-zh.readthedocs.io/zh/latest/ Tornado 是 Fr ...
- 【bzoj4551】TJOI2016&HEOI2016树
这题嘛…… 子树询问什么的,直接dfs序线段树无脑写,是吧…… 然后几分钟之内zcy就写出了这样的东西: #include<bits/stdc++.h> #define N 100005 ...
- JSON优缺点
总结: 1.占带宽小(格式是压缩的) 2. js通过eval()进行Json读取(便于客户端读取) 3. JSON支持多种语言(c.c++.PHP等),便于服务端解析 JSON (JavaScript ...