Codeforces 2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest L. Useful Roads
Berland capital contains n junctions and m roads connecting pairs of junctions. All roads are one-way. As you probably know Berland has two misfortunes: fools and roads.
It is one month before mayoral election. So it is time for current government to make the city better. To show that they care both about the infrastructure and about the budget, the government decided to repair only useful roads.
Current mayor thinks that a road from a junction u to a junction v is useful if there exists a simple path from City Hall to some junction containing the road (u, v). A path is called simple if it does not have any repeated junctions, i.e. contains each junction at most once. The City Hall is located at the junction 1.
Help Ministry of Road Transport and Highways to find all useful roads in the city.
The input contains several test cases. Each test case starts with a line containing two integers n, m (2 ≤ n ≤ 2·105;1 ≤ m ≤ 2·105) — the number of junctions and the number of roads in the city. The following m lines contain road descriptions, one description per line. A description consists of a pair of space-separated integers ui, vi (1 ≤ ui, vi ≤ n;ui ≠ vi) meaning that the i-th road leads from the junction ui to the junction vi. The junctions are numbered from 1 to n. The City Hall is located at the junction 1.
It is guaranteed that there is at most one road between a pair of junctions in each direction.
There is a blank line after each test case. The sum of n over all test cases in the input doesn't exceed 2·105. The same is true for m: the sum of m over all test cases in the input doesn't exceed 2·105.
Print two lines for each test case. On the first line print the number of useful roads. The second line should contain the indices of useful roads in ascending order. The roads are indexed from 1 to m in order of appearance in the input. Leave the second line empty if there are no useful roads in the city.
5 7
1 2
5 2
2 3
3 4
4 5
2 4
4 2 2 1
1 2
5
1 3 4 5 6
1
1
题意:
给出一张有向图(不保证联通...),判断那些边是有用的边...
有用边的定义:有一条从1号节点出发的简单路径覆盖这条边...
分析:
画画图想一想就会发现如果存在一条边(x,y),那么这是一条有用边当且仅当从1出发可以到达xy并且y不是x的必经点...
然后建出支配树来判断y是否是x的祖先就好了...
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
//by NeighThorn
using namespace std; const int maxn=200000+5; int n,m,ans,tot,f[maxn],fa[maxn],id[maxn],dfn[maxn],end[maxn],idom[maxn],semi[maxn],node[maxn]; stack<int> dom[maxn]; struct M{ int cnt,hd[maxn],to[maxn],nxt[maxn]; inline void init(void){
cnt=0;
memset(hd,-1,sizeof(hd));
} inline void add(int x,int y){
to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
} }G,tr; struct L{
int x,y,res;
}e[maxn]; inline int read(void){
char ch=getchar();int x=0;
while(!(ch>='0'&&ch<='9')) ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
} inline bool cmp(int x,int y){
return dfn[semi[x]]<dfn[semi[y]];
} inline int find(int x){
if(x==f[x])
return x;
int fx=find(f[x]);
node[x]=min(node[f[x]],node[x],cmp);
return f[x]=fx;
} inline void dfs(int x){
dfn[x]=++tot;id[tot]=x;
for(int i=tr.hd[x];i!=-1;i=tr.nxt[i])
if(!dfn[tr.to[i]])
fa[tr.to[i]]=x,dfs(tr.to[i]);
} inline void LT(void){
dfs(1);dfn[0]=tot<<1;
for(int i=tot,x;i>=1;i--){
x=id[i];
if(i!=1){
for(int j=G.hd[x],v;j!=-1;j=G.nxt[j])
if(dfn[G.to[j]]){
v=G.to[j];
if(dfn[v]<dfn[x]){
if(dfn[v]<dfn[semi[x]])
semi[x]=v;
}
else{
find(v);
if(dfn[semi[node[v]]]<dfn[semi[x]])
semi[x]=semi[node[v]];
}
}
dom[semi[x]].push(x);
}
while(dom[x].size()){
int y=dom[x].top();dom[x].pop();find(y);
if(semi[node[y]]!=x)
idom[y]=node[y];
else
idom[y]=x;
}
for(int j=tr.hd[x];j!=-1;j=tr.nxt[j])
if(fa[tr.to[j]]==x)
f[tr.to[j]]=x;
}
for(int i=2,x;i<=tot;i++){
x=id[i];
if(semi[x]!=idom[x])
idom[x]=idom[idom[x]];
}
idom[id[1]]=0;
} inline void dfs2(int x){
dfn[x]=++tot;
for(int i=tr.hd[x];i!=-1;i=tr.nxt[i])
dfs2(tr.to[i]);
end[x]=tot;
} signed main(void){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while(scanf("%d%d",&n,&m)!=EOF){
tr.init();G.init();tot=0;
for(int i=1;i<=n;i++)
f[i]=node[i]=i,dfn[i]=semi[i]=idom[i]=0;
for(int i=1;i<=m;i++)
e[i].x=read(),e[i].y=read(),tr.add(e[i].x,e[i].y),G.add(e[i].y,e[i].x);
LT();ans=0;tr.init();
for(int i=2;i<=tot;i++)
tr.add(idom[id[i]],id[i]);
tot=0;dfs2(id[1]);
for(int i=1,x,y;i<=m;i++){
x=e[i].x,y=e[i].y;
if(!dfn[x]||!dfn[y])
e[i].res=0;
else if(dfn[x]>dfn[y]&&dfn[x]<=end[y])
e[i].res=0;
else
e[i].res=1;
ans+=e[i].res;
}printf("%d\n",ans);
for(int i=1;i<=m;i++)
if(e[i].res)
printf("%d ",i);
puts("");
}
return 0;
}
By NeighThorn
Codeforces 2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest L. Useful Roads的更多相关文章
- Codeforces 2018-2019 ICPC, NEERC, Southern Subregional Contest
2018-2019 ICPC, NEERC, Southern Subregional Contest 闲谈: 被操哥和男神带飞的一场ACM,第一把做了这么多题,荣幸成为7题队,虽然比赛的时候频频出锅 ...
- 2018-2019 ICPC, NEERC, Southern Subregional Contest
目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Clou ...
- 2018-2019 ICPC, NEERC, Southern Subregional Contest (codeforces 1070)
A. 直接从状态(0,0)bfs, 这样一定是最小的 #include <iostream> #include <sstream> #include <algorithm ...
- 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Solution
从这里开始 题目列表 瞎扯 Problem A Find a Number Problem B Berkomnadzor Problem C Cloud Computing Problem D Gar ...
- Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结
第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...
- codeforce1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) 题解
秉承ACM团队合作的思想懒,这篇blog只有部分题解,剩余的请前往星感大神Star_Feel的blog食用(表示男神汉克斯更懒不屑于写我们分别代写了下...) C. Cloud Computing 扫 ...
- 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)
A. Find a Number 找到一个树,可以被d整除,且数字和为s 记忆化搜索 static class S{ int mod,s; String str; public S(int mod, ...
- 2018.10.20 2018-2019 ICPC,NEERC,Southern Subregional Contest(Online Mirror, ACM-ICPC Rules)
i207M的“怕不是一个小时就要弃疗的flag”并没有生效,这次居然写到了最后,好评=.= 然而可能是退役前和i207M的最后一场比赛了TAT 不过打得真的好爽啊QAQ 最终结果: 看见那几个罚时没, ...
- 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution
A. Find a Number Solved By 2017212212083 题意:$找一个最小的n使得n % d == 0 并且 n 的每一位数字加起来之和为s$ 思路: 定义一个二元组$< ...
随机推荐
- BZOJ3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛(dp)
题意 约翰要带N(1≤N≤100000)只牛去参加集会里的展示活动,这些牛可以是牡牛,也可以是牝牛.牛们要站成一排.但是牡牛是好斗的,为了避免牡牛闹出乱子,约翰决定任意两只牡牛之间至少要有K( ...
- JAVA 优先获取外网Ip,再获取内网Ip
1.获取内网Ip private String getLocalhostIp(){ String hostAddress = ""; try { InetAddress addre ...
- 解决国内网络Python2.X 3.X PIP安装模块连接超时问题
pip国内的一些镜像 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/si ...
- 04构建之法读书笔记——IT行业的创新
IT行业的创新: 1.创新的迷思: 灵光一闪现,伟大的创新就紧随其后:大家都喜欢创新:好的想法会赢:创新者都是一马当先:要成为领域的专家,才能创新:技术的创新是关键:成功的团队更能创新 2.创新的时机 ...
- python实现导出excel表(前端+后端)
之前在做项目管理系统的时候需要实现将数据导出到excel表的功能,搜索之后发现了python的xlwt模块可以很好的实现这项功能. 首先是导入xlwt模块: import xlwtfrom io im ...
- Python学习笔记:装饰器
Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...
- 2017 ACM-ICPC EC-Final ShangHai(思维乱搞赛)
感觉全是思维乱搞题. Gym - 101775J Straight Master 给你n种扑克,你每次可以出连续的3 ~ 5 张,问你能否出完. Sample Input 2 13 1 2 2 1 0 ...
- char* 与char[]区别
[转] 最近的项目中有不少c的程序,在与项目新成员的交流中发现,普遍对于char *s1 和 char s2[] 认识有误区(认为无区别),导致有时出现“难以理解”的错误.一时也不能说得很明白,网上也 ...
- 读《深入理解jvm虚拟机》之长期存活对象进入老年代,有感!!!!
关于这一段代码 有几个不是让人很理解的地方,我一一说来. 1.Desired survivor size 524288 bytes 关于这个512KB空间是怎么来的,JVM有这样一个参数: -XX:T ...
- sql:where中多种状况简便写法
字段名:Bran,block,are ,store 四个字段中存在值等于0或者不等于0,两种情况.where中如果用if等条件判断会有16中组合,如果采用where中的条件就避免了这个情况. decl ...