zoukankan      html  css  js  c++  java
  • CDOJ 1288 旅游的Final柱 构造题

    旅游的Final柱

    题目连接:

    http://acm.uestc.edu.cn/#/problem/show/1288

    Description

    柱神要去打Final啦~(≧▽≦)/~啦啦啦

    柱神来到了异国他乡的普吉岛,柱神决定好好游览一番。

    普吉岛的景点编号为11到NN,景点之间由双向的道路连接着,所有的道路的长度都是11。

    柱神希望访问所有的景点,但是又不想耽搁太长的时间,所以柱神决定每天访问一个景点。

    为了好好陶冶情操,柱神并不在路上花费太多的时间,所以柱神不会在连续的两天访问两个最短距离超过KK的景点。

    由于柱神忙着打Final,所以旅行的方案就交个你了。

    Input

    第一行为两个整数N,KN,K,其中4<=N<=5004<=N<=500,3<=K<=N−13<=K<=N−1。

    接下来NN行NN列,第ii行jj列的值aij=1aij=1或者aij=0aij=0。

    如果aij=1aij=1,表示从景点ii到景点jj有一条长为11的道路,如果aij=0aij=0,则表示从ii到jj没有直接的道路。

    图保证联通。

    注意哦:数据以字符串的形式给出,只包含0和1,且aii=0

    Output

    输出一个11到NN的排列,第ii个数表示第ii天访问的景点编号。输出任意一组解即可。

    Sample Input

    4 3
    0100
    1010
    0101
    0010

    Sample Output

    1 3 2 4

    Hint

    题意

    题解:

    这道题给了你一个无向图,以及一个k,让你输出一个旅游方案,使得这个旅游方案恰好旅行每个点一次,且相邻的两个点之间的距离小于k。

    这道题怎么做呢?

    话音刚落,小郭同学发言了:“我觉得这个k的数据范围是500,我感觉瞎dfs一波或者bfs一波,再加点点随机化就好了。”

    然后小郭同学非常开心的就去写了几发随机化,然后TLE,WA……

    暴力显然是过不了了,那应该怎么做呢?

    这是一道构造题,应该想想一些聪慧的办法。

    这道题最困难的情况是什么呢?

    答:他给你的那个无向图就是一颗树,且k就等于3。如果这个能够解决,那么显然原题目也就能解决啦。

    这个怎么做呢?想啊想啊想啊。

    想到了!

    我们随便抓一个点,当做这个树的根,然后把这个点染成白色。然后剩下的点,与白点相连的点就染成黑色,与黑色相连的点就染成白色。

    现在这棵树上的点,就只有黑点和白点了。

    然后我们这样做:

    定义函数dfs(x):
    如果现在这个点是白点,那就输出这个点。
    走向下一个与这个点相邻的点v,进行函数dfs(v)
    如果现在这个点是黑点,那就输出这个点。

    这样做之后,我们可以显然的发现,连续输出的两个点,如果都是黑色或者白色的话,距离等于2。连续输出的两个点是不同的颜色的话,距离为1或者3。

    距离为3的情况是:
    白4
    |
    黑3
    |
    白1--黑2

    这样会输出1,2,4,3。

    啦啦啦,显然这种构造方式,可以使得任意输出的连续两个点的距离小于等于3啦。

    然后这道题就解决了~

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 505;
    string s;
    vector<int>E[maxn];
    int vis[maxn];
    void dfs(int x,int flag)
    {
        vis[x]=1;
        if(flag==0)printf("%d ",x);
        for(int i=0;i<E[x].size();i++)
        {
            if(vis[E[x][i]])continue;
            dfs(E[x][i],!flag);
        }
        if(flag==1)printf("%d ",x);
    }
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            for(int j=0;j<s.size();j++)
                if(s[j]=='1')E[i].push_back(j+1);
        }
        dfs(1,0);
    }
  • 相关阅读:
    UFLDL深度学习笔记 (四)用于分类的深度网络
    UFLDL深度学习笔记 (三)无监督特征学习
    UFLDL深度学习笔记 (二)SoftMax 回归(矩阵化推导)
    UFLDL深度学习笔记 (一)反向传播与稀疏自编码
    【2016内推】计算机找工作面经
    关于最优化中的若干问题
    关于extern "C" 的用法
    浅谈多核CPU、多线程、多进程
    并发与并行
    多进程与多线程
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5291517.html
Copyright © 2011-2022 走看看