• Evanyou Blog 彩带


      题目传送门

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

     

    输入输出样例

    输入样例#1: 
    6 7
    1 3
    1 4
    3 2
    4 2
    5 6
    6 5
    3 4
    输出样例#1: 
    3
    输入样例#2: 
    6 8
    1 3
    1 4
    3 2
    4 2
    5 6
    6 5
    3 4
    4 3
    输出样例#2: 
    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+7;
    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=0; bool flag=false;
        while( ch<'0' || ch>'9' ) {
            if( ch=='-' ) flag=true; ch=getchar();
        }
        while( ch>='0' && ch<='9' ) {
            num=num*10+ch-'0'; 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]=1;
        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]=1;
        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]=0;
                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=1; i<=m; ++i)
            edge[i].u=read(), edge[i].v=read(), add(edge[i].u,edge[i].v);
        dfs(1,vis1,h1,to1,nxt1); dfs(2,vis2,h2,to2,nxt2);
        if( !vis1[2] ) puts("0"), exit(0);
        for(int i=1; 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=1; i<=n; ++i)
            if( !dfn[i] && vis1[i] ) tarjan(i);
        if( scc[1]==scc[2] ) puts("inf"), exit(0);
        for(int i=1; i<=n; ++i)
            if( siz[scc[i]]>1 && vis1[i] && vis2[i] ) puts("inf"), exit(0);
        q.push(1);ans[1]=1;
        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
    ",ans[2]);
        return 0;
    }
  • 相关阅读:
    解决使用git出现 The file will have its original line endings in your working directory
    SpringBoot集成flowable碰见DMN不能初始化
    CF268D Wall Bars
    CF1327F AND Segments
    P2900 [USACO08MAR]Land Acquisition G
    CF279B Books
    CF859E Desk Disorder
    CF1147B Chladni Figure
    CF1147E Rainbow Coins
    P3565 [POI2014]HOT-Hotels
  • 原文地址:https://www.cnblogs.com/cytus/p/9838870.html
Copyright © 2020-2023  润新知