L. Useful Roads
time limit per test:4 seconds
memory limit per test:512 megabytes
input:standard input
output:standard output

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.

Input

The input contains several test cases. Each test case starts with a line containing two integers nm (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 uivi (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.

Output

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.

Examples
input
5 7
1 2
5 2
2 3
3 4
4 5
2 4
4 2 2 1
1 2
output
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的更多相关文章

  1. Codeforces 2018-2019 ICPC, NEERC, Southern Subregional Contest

    2018-2019 ICPC, NEERC, Southern Subregional Contest 闲谈: 被操哥和男神带飞的一场ACM,第一把做了这么多题,荣幸成为7题队,虽然比赛的时候频频出锅 ...

  2. 2018-2019 ICPC, NEERC, Southern Subregional Contest

    目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Clou ...

  3. 2018-2019 ICPC, NEERC, Southern Subregional Contest (codeforces 1070)

    A. 直接从状态(0,0)bfs, 这样一定是最小的 #include <iostream> #include <sstream> #include <algorithm ...

  4. 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 ...

  5. Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结

    第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...

  6. codeforce1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) 题解

    秉承ACM团队合作的思想懒,这篇blog只有部分题解,剩余的请前往星感大神Star_Feel的blog食用(表示男神汉克斯更懒不屑于写我们分别代写了下...) C. Cloud Computing 扫 ...

  7. 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, ...

  8. 2018.10.20 2018-2019 ICPC,NEERC,Southern Subregional Contest(Online Mirror, ACM-ICPC Rules)

    i207M的“怕不是一个小时就要弃疗的flag”并没有生效,这次居然写到了最后,好评=.= 然而可能是退役前和i207M的最后一场比赛了TAT 不过打得真的好爽啊QAQ 最终结果: 看见那几个罚时没, ...

  9. 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$ 思路: 定义一个二元组$< ...

随机推荐

  1. 【C++学习笔记】强大的算法——spfa

    spfa的定义 PFA算法的全称是:Shortest Path Faster Algorithm,用于求单源最短路,由西南交通大学段凡丁于1994年发表.当给定的图存在负边时,Dijkstra算法就无 ...

  2. SPOJ1043 GSS1(线段树)

    题意 给出$n$个数,每次询问区间$(l, r)$内最大字段和 Sol 在合并子树的时候,答案仅有四种情况 打四个标记维护即可 查询同理,用类似update的方式合并 注意查询的时候不能按照以前的方式 ...

  3. 十四、MySQL UPDATE 查询

    MySQL UPDATE 查询 如果我们需要修改或更新 MySQL 中的数据,我们可以使用 SQL UPDATE 命令来操作.. 语法 以下是 UPDATE 命令修改 MySQL 数据表数据的通用 S ...

  4. Nginx 配置支持 WAF

    WAF(Web Application Firewall),中文名叫做“Web应用防火墙” WAF的定义是这样的:Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提 ...

  5. 17.VUE学习之- v-for指令的使用方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. C#小知识点积累

    1.sealed 修饰符 概念: C#提出了一个密封类(sealed class)的概念,帮助开发人员来解决这一问题. 密封类在声明中使用sealed 修饰符,这样就可以防止该类被其它类继承.如果试图 ...

  7. HDU 5739 Fantasia 双连通分量 树形DP

    题意: 给出一个无向图,每个顶点有一个权值\(w\),一个连通分量的权值为各个顶点的权值的乘积,一个图的权值为所有连通分量权值之和. 设删除顶点\(i\)后的图\(G_i\)的权值为\(z_i\),求 ...

  8. Redis实现之数据库(三)

    过期键删除策略 在Redis实现之数据库(二)一小节中,我们知道了数据库键的过期时间都保存在过期字典中,又知道了如果根据过期时间去判断一个键是否过期,现在剩下的问题是:如果一个键过期了,那么它什么时候 ...

  9. django 开发之模型以及静态问题和图片的使用

    使用Django的模型,基本步骤: 1.创建model 2.加入到admin.py中去 3.执行生成迁移:python manage.py makemigrations blog 4.执行迁移,生成表 ...

  10. RF,GBDT,XGBoost,lightGBM的对比

    转载地址:https://blog.csdn.net/u014248127/article/details/79015803 RF,GBDT,XGBoost,lightGBM都属于集成学习(Ensem ...