洛谷P4645 [COCI2006-2007 Contest#7] BICIKLI [Tarjan,拓扑排序]
BICIKLI
题意翻译
给定一个有向图,n个点,m条边。请问,1号点到2号点有多少条路径?如果有无限多条,输出inf,如果有限,输出答案模10^9的余数。
两点之间可能有重边,需要看成是不同的路径。
题目描述
A bicycle race is being organized in a land far, far away. There are N town in the land, numbered 1 through N. There are also M one-way roads between the towns. The race will start in town 1 and end in town 2. How many different ways can the route be set? Two routes are considered different if they do not use the exact same roads.
输入输出格式
输入格式:
The first line of input contains two integers N and M (1 ≤ N ≤ 10 000, 1 ≤ M ≤ 100 000), the number of towns and roads. Each of the next M lines contains two different integers A and B, representing a road between towns A and B. Towns may be connected by more than one road.
输出格式:
Output the number of distinct routes that can be set on a single line. If that number has more than nine digits, output only the last nine digits of the number. If there are infinitely many routes, output "inf".
输入输出样例
6 7
1 3
1 4
3 2
4 2
5 6
6 5
3 4
3
6 8
1 3
1 4
3 2
4 2
5 6
6 5
3 4
4 3
inf
说明
本题数据已经被更改,无需保留前导0
分析:
考试的题,考场上居然没想到用$Tarjan$来处理环,傻逼的打了几个$DFS$,然后开心的$WA$成狗。
首先不难想到$inf$的情况就是$1$到$2$的任一路径上有环出现,那么我们可以这么处理:先正反向建边,然后分别以$1,2$为起点$DFS$,然后标记那些点是$1$到$2$的路径上的点,再就可以缩点重建图,如果发现某个强联通分量既是路径上的点而且大小又超过$1$那么就是$inf$,否则就跑拓扑排序记录路径数就行了。
Code:
//It is made by HolseLee on 23rd Oct 2018
//Luogu.org P4645
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mod (1000000000)
using namespace std; const int N=1e5+;
int n,m,head[N],cnte,siz[N],cnt1,cnt2,dg[N];
int dfn[N],low[N],scc[N],idx,tot,sta[N],top,ans[N];
int h1[N],to1[N],nxt1[N],h2[N],to2[N],nxt2[N];
bool vis1[N],vis2[N],ins[N];
struct Edge {
int u,v,to,nxt;
}e[N],edge[N];
queue<int>q; inline int read()
{
char ch=getchar(); int num=; bool flag=false;
while( ch<'' || ch>'' ) {
if( ch=='-' ) flag=true; ch=getchar();
}
while( ch>='' && ch<='' ) {
num=num*+ch-''; ch=getchar();
}
return flag ? -num : num;
} inline void add(int x,int y)
{
to1[++cnt1]=y, nxt1[cnt1]=h1[x], h1[x]=cnt1;
to2[++cnt2]=x, nxt2[cnt2]=h2[y], h2[y]=cnt2;
} inline void add_edge(int x,int y)
{
e[++cnte].to=y;
e[cnte].nxt=head[x];
head[x]=cnte;
} void dfs(int x,bool *vis,int *h,int *to,int *nxt)
{
vis[x]=;
for(int i=h[x],y; i; i=nxt[i]) {
y=to[i];
if( !vis[y] ) dfs(y,vis,h,to,nxt);
}
} void tarjan(int x)
{
dfn[x]=low[x]=++idx; ins[x]=;
sta[++top]=x; int y;
for(int i=head[x]; i; i=e[i].nxt) {
y=e[i].to;
if( !dfn[y] ) {
tarjan(y);
low[x]=min(low[x],low[y]);
} else if( ins[y] ) {
low[x]=min(low[x],dfn[y]);
}
}
if( dfn[x]==low[x] ) {
tot++;
do{
y=sta[top--]; ins[y]=;
scc[y]=tot; siz[tot]++;
}while(y!=x);
}
} int main()
{
freopen("bicikli.in","r",stdin);
freopen("bicikli.out","w",stdout);
n=read(), m=read();
for(int i=; i<=m; ++i)
edge[i].u=read(), edge[i].v=read(), add(edge[i].u,edge[i].v);
dfs(,vis1,h1,to1,nxt1); dfs(,vis2,h2,to2,nxt2);
if( !vis1[] ) puts(""), exit();
for(int i=; i<=m; ++i) {
if( vis1[edge[i].u] && vis1[edge[i].v] )
add_edge(edge[i].u,edge[i].v), dg[edge[i].v]++;
}
for(int i=; i<=n; ++i)
if( !dfn[i] && vis1[i] ) tarjan(i);
if( scc[]==scc[] ) puts("inf"), exit();
for(int i=; i<=n; ++i)
if( siz[scc[i]]> && vis1[i] && vis2[i] ) puts("inf"), exit();
q.push();ans[]=;
int x,y;
while( !q.empty() ) {
x=q.front(); q.pop();
for(int i=head[x]; i; i=e[i].nxt) {
y=e[i].to;
ans[y]=(ans[y]+ans[x])%mod;
if( !(--dg[y]) ) q.push(y);
}
}
printf("%d\n",ans[]);
return ;
}
洛谷P4645 [COCI2006-2007 Contest#7] BICIKLI [Tarjan,拓扑排序]的更多相关文章
- 洛谷P4581 [BJOI2014]想法(玄学算法,拓扑排序)
洛谷题目传送门 萝卜大毒瘤 题意可以简化成这样:给一个DAG,求每个点能够从多少个入度为\(0\)的点到达(记为\(k\)). 一个随机做法:给每个入度为\(0\)的点随机一个权值,在DAG上求出每个 ...
- 动态规划 洛谷P4017 最大食物链计数——图上动态规划 拓扑排序
洛谷P4017 最大食物链计数 这是洛谷一题普及/提高-的题目,也是我第一次做的一题 图上动态规划/拓扑排序 ,我认为这题是很好的学习拓扑排序的题目. 在这题中,我学到了几个名词,入度,出度,及没有环 ...
- 洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
P3065 [USACO12DEC]第一!First! 题目链接:https://www.luogu.org/problemnew/show/P3065 题目描述 Bessie一直在研究字符串.她发现 ...
- 洛谷 P2046 BZOJ 2007 海拔(NOI2010)
题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...
- 洛谷P1080 国王游戏 python解法 - 高精 贪心 排序
洛谷的题目实在是裹脚布 还编的像童话 这题要 "使得获得奖赏最多的大臣,所获奖赏尽可能的少." 看了半天都觉得不像人话 总算理解后 简单说题目的意思就是 根据既定的运算规则 如何排 ...
- 【洛谷 P1452】 Beauty Contest (二维凸包,旋转卡壳)
题目链接 旋转卡壳模板题把. 有时间再补总结吧. #include <cstdio> #include <cmath> #include <algorithm> u ...
- 洛谷 P1131 [ ZJOI 2007 ] 时态同步 —— 树形DP
题目:https://www.luogu.org/problemnew/show/P1131 记录 x 子树内同步的时间 f[x],同步所需代价 g[x]: 直接转移即可,让该儿子子树与其它儿子同步, ...
- BZOJ 1634 洛谷2878 USACO 2007.Jan Protecting the flowers护花
[题意] 约翰留下他的N只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小 ...
- 洛谷 P1177 【模板】快速排序【13种排序模版】
P1177 [模板]快速排序 题目描述 利用快速排序算法将读入的N个数从小到大排序后输出. 快速排序是信息学竞赛的必备算法之一.对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成.( ...
随机推荐
- scrapy爬取天气数据
看了scrapy,打算构建自己的天气数据,目标源:就是你了,中国天气网! 仔细点两下这个网站,发现可以由各个省.直辖市到省市所属的地级市,再到各县,页面在这: 点开就可以看到中国所有的省.直辖市,但港 ...
- SharePoint 项目的死法(二)
说实话, 做SharePoint项目或者任何信息化项目并不是个容易的事情, 但成功的IT项目对于一个企业来说也许意味着很多, 从我的观察来看, 大部分的成功的信息化项目给企业所带来的回报都远远超过其所 ...
- promise顺序执行,返回结果存放在数组
遇到面试的一个编程题:三个返回promise对象的异步操作,让你写一个函数可以将这些操作顺序执行,并返回一个数组包含三个异步对象的结果 异步对象: // 异步函数a var a = function ...
- Python练习-装饰器版-为什么我的用户总被锁定
参考代码如下: 1.用户登录程序流程控制代码: # 编辑者:闫龙 if __name__ == '__main__': import UserLoginFuncation LoclCount=[]; ...
- 单调栈(G - Sliding Window POJ - 2823 )
题目链接:https://cn.vjudge.net/contest/276251#problem/G 题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值 ...
- 线段树(dfs序建树加区间更新和单点查询)
题目链接:https://cn.vjudge.net/contest/66989#problem/J 记录一下这道折磨了我一天的题,.... 具体思路: 具体关系可通过dfs序建树,但是注意,在更新以 ...
- 子查询优化--explain与profiling分析语句
今天想的利用explain与progiling分析下语句然后进行优化.本文重点是如何通过explain与profiling分析SQL执行过程与性能.进而明白索引的重要性. 表的关系如下所示: 原始的查 ...
- javascript中用闭包递归遍历树状数组
做公司项目时,要求写一个方法,方法的参数为一个菜单数组集合和一个菜单id,菜单数组的格式为树状json,如下面所示: [{"id":28,"text":&quo ...
- Python Challenge 第 5 关攻略:peak
# -*- coding: utf-8 -*- # @Time : 2018/9/26 14:03 # @Author : cxa # @File : pickledemo.py # @Softwar ...
- ActiveMQ 使用场景
ActiveMQ 安装测试就不做介绍了,下面我说说ActiveMQ 使用场景.(松耦合与ActiveMQ) 1.非均匀应用集成 ActiveMQ 中间件用Java语言编写,因此自然提供Java客户端 ...