[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.谈谈你对图结构的认识及学习体会 本章学习了图结构的相关知识,图形结构属于复杂的非线性数据结构,在实际应用中很多问题可以用图来描述.在图结构中,每个元素可以有 ...
随机推荐
- 玩一下易语言 "和"字有多种读音,注定了它的重要性!!
变量名 类型 静态 数组 备注 拼音 文本型 0 测试的汉字 文本型 有几种发音 整数型 i 整数型 测试用的汉字 = “和” 有几种发音 = 取发音数目 ...
- perl6 修改文件并覆盖
use v6; my $filename = 'data.txt'; my $data = slurp $filename; say $data; $data ~~ s/'4'/'ABC'/; say ...
- Python3 Socket和SocketServer 网络编程
socket只能实现同时一个服务和一个客户端实现交互,socketserver可以实现多个客户端同时和服务端交互 1.利用Socket编写简单的同一个端口容许多次会话的小案例: 服务端: #!/usr ...
- monkey测试===ios-monkey测试工具
iOSmonkey测试工具: crashmonkey 特点: 支持**真机测试.模拟器测试** 支持收集**系统日志(Systemlog)**.**崩溃日志(Crashlog)**.***instru ...
- Java中volatile修饰符,不稳定标记的用法笔记
今天学java特性时,发现了volatile修饰符,这个修饰符修饰的变量告诉java编译器忽略优化机制,这样的优势是: java优化后,寄存器会缓存内存里的变量,另一个线程修改这个变量的内存时,不会同 ...
- Win10默认图片查看器更改
Win10自带的图片查看器不是很习惯,其背景乌漆嘛黑,宽扁的额头让人想起了黑边火腿肠手机,无法直视.怀念Win7和Win8.1的图片查看器,一个鼠标滚轮缩放自如的酸爽感觉.但却遗憾地发现,并不能直观地 ...
- 【bzoj1072】SCOI2007排列
状压dp,f[i][j]表示当前取了i,模数余j的状态. 然后向后推,枚举可能的数即可. 注意每个数存在重复,最后要除以相应出现次数的阶乘. #include<bits/stdc++.h> ...
- Linq to SQL 小结
前天开始看这方面的资料,虽然看了网上对比 sql和linq的速度,万条数据可能要慢1/4左右的数度,但是介于的方便,还是学了 首先看看linq的基本语法: FROM XX IN DATASOURCE ...
- ios IAP 内购验证
参考我之前的笔记 苹果内购笔记,在客户端向苹果购买成功之后,我们需要进行二次验证. 二次验证 IOS在沙箱环境下购买成功之后,向苹果进行二次验证,确认用户是否购买成功. 当应用向Apple服务器请求购 ...
- java-增强for循环
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); lis ...