zoukankan      html  css  js  c++  java
  • Tourist Attractions

    在美丽的比特镇一共有 n 个景区,编号依次为 1 到 n,它们之间通过若干条双向道路连接。
    Byteasar 慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起 4 个景区的门票费。他可以在任意景区开始游览,然后结束在任意景区。
    Byteasar 的旅游习惯比较特殊,一旦他路过了一个景区,他就一定会进去参观,并且他永远不会参观同一个景区两次。所以他想知道,有多少种可行的旅游路线,使得他可以恰好参观 4 个景区呢?
    即,有多少条简单路径恰好经过了 4 个点。

    Input
    第一行包含两个整数 n,表示景区的总数。
    第 2 至第 n + 1 行,每行一个长度为 n 的 01 字符串,第 i + 1 行第 j 个字符为 0 表示 i 和 j 之间
    没有道路,为 1 表示有一条道路。
    输入数据保证 (i; j) 的连接情况等于 (j; i) 的连接情况,且 (i; i) 恒为 0。

    Output
    输出一行一个整数,即可行的路线总数。

    Examples
    tour.in
    4
    0101
    1010
    0101
    1010

    tour.out
    8

    8 条路线分别为:
    1->2->3->4,4->3->2->1,
    2->3->4->1,1->4->3->2,
    3->4->1->2,2->1->4->3,
    4->1->2->3,3->2->1->4

    分析:
    先抛开正解,看一下部分分的算法
    70% 的数据,n<=300
    假设路径是 a->b->c->d,考虑枚举中间这条边 b->c,
    计算有多少可行的a和d
    设in[x]表示点x的度数(出入边条数),那么边b->c对答案的贡献为
    (in[b]-1)(in[c]-1)-经过b->c这条边的三元环个数
    计算三元环的个数只需要枚举除b,c之外的另一个点即可。
    时间复杂度 O(n^3)

    70 分算法的瓶颈在于三元环计数
    设Sx表示所有和x有边的点的集合,
    那么其实就是统计

    这里写图片描述

    将S用二进制压位存储即可
    时间复杂度 O(n^3/32)

    挺好理解,然而二进制压位为什么的,我表示??

    先献上70分代码:
    注意:开long long!!!

    这里写代码片
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    const int N=1501;
    int mp[N][N];
    struct node{
        int x,y,nxt;
    };
    node way[N*N];
    int st[N],tot=0;
    int n,out[N];
    long long ans=0;
    
    void add(int u,int w)
    {
        tot++;
        way[tot].x=u; way[tot].y=w; way[tot].nxt=st[u]; st[u]=tot;
    }
    
    void solve()  //顺序不同也视为不同 
    {
        int i,tt;
        for (i=1;i<=tot;i++)
        {
            int r1=way[i].x;
            int r2=way[i].y;
            ans=ans+(long long)(out[r1]-1)*(out[r2]-1);
            tt=0;
            for (int j=1;j<=n;j++)
                if (j!=r1&&j!=r2)
                   if (mp[r1][j]&&mp[r2][j]) tt++;
            ans=ans-(long long)tt;  //三元环的个数    
        }
    }
    
    int main()
    {
        //freopen("tour.in","r",stdin);  
        //freopen("tour.out","w",stdout);
        scanf("%d",&n);
        char ch;
        scanf("%c",&ch);
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++) 
            {
                scanf("%c",&ch);
                if (ch=='1') add(i,j),out[i]++;
                mp[i][j]=ch-'0';
            }
            scanf("%c",&ch);
        }
        solve();
        printf("%lld",ans);   //开ll 
        return 0;
    }
  • 相关阅读:
    通过this调用本类属性和本类方法
    使用构造方法接收引用数据类型
    JAVA回形数
    Bt(宝塔面板)忘记用户名密码的解决方案
    关于xshell远程连接密码呈现灰色无法填写的问题
    ubunt系统创建定时任务
    阿里云服务器如何初始化
    解决laravel 配置路由时除 “/”路由 以外 ,所有路由访问不到的情况
    laravel 5.2 使用 captcha 实现 验证码
    在laravel中如何使用事务
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673530.html
Copyright © 2011-2022 走看看