People like People ZJU 2682 强联通+记忆化搜索

题意:

 给定一个有向图.

 求一个最大的集合,是所有属于这个集合的点都满足以下条件:

1.出度不为0

2.指向的点都在这个集合内

3.有属于这个集合的点指向这个点

题解:

 我的做法是:对图缩点后,枚举每个点,以这个点作起点,并且这个点是由大于等于2个点缩点而得到的,然后这个点为根,以他能访问到的点构成树,如果所有叶子都是大于等于两个点以上缩点得到的,则说明该树构成一个合法的集合.取最大的合法集合即可.

/*
 * File:   main.cpp
 * Author: swordholy
 *
 * Created on 2011年3月6日, 下午1:27
 */

#include <cstdlib>
#include <iostream>
#include <memory.h>
#include <stdio.h>

#include<iostream>
#include<vector>
using namespace std;
#define MY_MAX 100004
bool visited[MY_MAX], instack[MY_MAX];
int stack[MY_MAX], top;
int N, M;
vector<int> graph[MY_MAX];
vector<int> g[MY_MAX]; //rebuilded
int dfn[MY_MAX], low[MY_MAX];
int color[MY_MAX], colorn[MY_MAX];
int INDEX, num, en;

struct edge {
    int x, y;
};
edge e[MY_MAX];

int min(int x, int y) {
    if (x < y) return x;
    else return y;
}

void tarjan(int u) {
    int v;
    dfn[u] = low[u] = INDEX++;
    stack[++top] = u;
    instack[u] = true;
    visited[u] = true;
    for (size_t i = 0; i < graph[u].size(); ++i) {
        v = graph[u][i];
        if (!visited[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (instack[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        ++num;
        color[u] = num;
        do {
            v = stack[top--];
            color[v] = num;
            instack[v] = false;
        } while (v != u);
    }
}
int d[100005];

int dfs(int x) {
    int i, j, sum;
    if (d[x] != -1) return d[x];
    d[x] = 0;
    if ((g[x].size() == 0)) {
        if (colorn[x] >= 2) {d[x]=colorn[x];return colorn[x];}
        else return 0;
    }
    sum = colorn[x];
    for (i = 0; i < g[x].size(); i++) {
        int temp = dfs(g[x][i]);
        if (temp == 0) return 0;
        sum += temp;
    }
    d[x] = sum;
    return sum;
}

/*

 */
int main(int argc, char** argv) {
    int n, i, j, t, u, m, vv, id, idn, v[5];
    cin >> t;
    for (u = 1; u <= t; u++) {
        scanf("%d %d", &n, &m);
        for (i = 1; i <= n; i++)
            graph[i].clear();
        en = 0;
        for (vv = 1; vv <= m; vv++) {
            scanf("%d %d", &id, &idn);
            for (i = 1; i <= idn; i++) {
                scanf("%d", &v[i]);
                graph[id].push_back(v[i]);
                ++en;
                e[en].x = id;
                e[en].y = v[i];
            }
        }
   /*     for(i=1;i<=5;i++)
        {
            for(j=0;j<graph[i].size();j++)
                printf("%d ",graph[i][j]);
        printf("/n");
        }*/
        ///
        //init....
        top = 0;
        num = 0;
        INDEX = 1;
        memset(visited, 0, sizeof (visited));
        memset(instack, 0, sizeof (instack));
        //
        //calc color by tarjan
        for (i = 1; i <= n; i++)
            if (!visited[i]) tarjan(i);
        //
        //rebuild a map
        for (i = 1; i <= n; i++)
            g[i].clear();
        for (i = 1; i <= en; i++)
            if (color[e[i].x] != color[e[i].y])
                //不能自己指向自己
                g[color[e[i].x]].push_back(color[e[i].y]);
        ///
        memset(colorn, 0, sizeof (colorn));
        for (i = 1; i <= n; i++)
            colorn[color[i]]++;
        bool fl = true;
        memset(d, -1, sizeof (d));
        int ans = 0;
        for (i = 1; i <= num; i++)
            if (colorn[i] >= 2) {
                int v = dfs(i);
                if (v > ans) ans = v;
            }
        printf("%d/n", ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ZJU-I型机械臂是一种由浙江大学机器人研究所开发的六自由度机械臂,具有高速、精度和可靠性等特点。机械臂的运动控制是机器人中的重要研究领域之一,其中点到点轨迹规划是机器人在运动过程中最基础和常用的一种方式,也是机械臂控制的核心问题之一。 点到点轨迹规划的目标是通过给定的起点和终点,计算出机械臂的运动轨迹,使机械臂在运动过程中满足机械臂轨迹的连续性、平滑性、可控性等要求。在过去的研究中,经典的点到点轨迹规划方法包括插值法、线性规划法、最小能量法等。 如果使用Python实现机械臂的点到点轨迹规划,可以采用Robotics Toolkit(简称robot)这个模块。robot模块提供了各种从轨迹规划、控制到仿真的功能,可用于ROS、Vrep、Webots等机器人仿真软件。使用robot模块,可以通过几行代码实现机械臂的点到点轨迹规划,例如: ``` from roboticstoolkit import robot from roboticstoolkit.robots import zju # 初始化机器人 zju_arm = robot.Robot('zju', zju.URDF) # 设定起点和终点 start = [0, 0, 0, 0, 0, 0] goal = [0, 1, 1, 0.5, 0, 0] # 计算机械臂的轨迹 path = zju_arm.get_trajectory(start, goal) # 控制机械臂运动到终点 zju_arm.move_to(goal) ``` 其中,`roboticstoolkit`和`roboticstoolkit.robots`都是导入的Python模块,`zju`是机械臂的URDF定义文件,`start`和`goal`是起点和终点的坐标,`get_trajectory()`函数会返回计算得到的机械臂轨迹,`move_to()`函数则控制机械臂运动到终点。 总之,使用Python实现ZJU-I型机械臂的点到点轨迹规划相对简单,只需要导入相应的模块,并根据需要设置机械臂的各种参数,即可轻松实现机械臂的控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值