[Ответить в тред] Ответить в тред

02/12/16 - Конкурс визуальных новелл доски /ruvn/
15/11/16 - **НОВЫЙ ФУНКЦИОНАЛ** - Стикеры
09/10/16 - Открыта доска /int/ - International, давайте расскажем о ней!

Check this out!

Новые доски: /2d/ - Аниме/Беседка • /wwe/ - WorldWide Wrestling Universe • /ch/ - Чатики и конфочки • /int/ - International • /ruvn/ - Российские визуальные новеллы • /math/ - Математика • Создай свою

[Назад][Обновить тред][Вниз][Каталог] [ Автообновление ] 72 | 13 | 10
Назад Вниз Каталог Обновить

Аноним 08/03/17 Срд 13:24:26  148325445  
Безымянный.png (13Кб, 753x392)
Есть тут аноны, разбирающиеся в графах? Есть задача, бьюсь над ней уже третий день. Мне дают неориентированный граф, не содержащий петель и кратных ребер. Также мне дают некоторое количество пар вершин. Мне нужно найти кол-во точек сочленения в диапазоне этих вершин, не считая начальной и конечной вершины.

Вот строчка из оригинального текста(вы поймете, зачем я её вставил сюда): Для каждой описанной пары выведите на отдельной строке единственное число --- количество вершин c, таких, что любой путь из ai в bi, проходит через c

Привожу пример:
1. Мне даётся пкрл граф и одна пара(1, 5). Точки сочленения между этими вершинами - это 2 и 3, значит ответ - 2(две вершины).
2. Тот же граф, но пара (9, 7). Программа должна вывести 0, т.к. нету такого пути из 9 в 7, чтобы он проходил постоянно по одной и той же вершине(точка сочленения есть, но вершины такой нет, так что можно сказать, что это частный случай).

С нахождением точек сочленения проблем нет, но я не знаю, как вычленить из графа именно нужный мне путь. То что делается это всё поиском в глубину, я думаю, это ясно. Так вот если ввести 9 и 7, то поиск пойдёт от 1 до 6, посчитает точки сочленения, это (1, 2, 3), вернётся в единицу, пробежит 7, 8 и 9 и выдаст мне ответ 3, т. к. он пробежит весь граф, а мне нужен диапазон именно от 9 до 7, чтобы оно не ходило по лишним вершинам.

К слову, подразумевается, что всё это можно сделать только поисками в глубину.
Аноним 08/03/17 Срд 13:27:47  148325609
бамп
Аноним 08/03/17 Срд 13:37:05  148326065
Бамп
Аноним 08/03/17 Срд 13:40:36  148326223
Бамп
Аноним 08/03/17 Срд 13:40:59  148326235
Бпм
Аноним 08/03/17 Срд 13:41:19  148326252
Бамп
Аноним 08/03/17 Срд 13:41:35  148326258
Ьампбпм
Аноним 08/03/17 Срд 13:41:51  148326273
Ьамп
Аноним 08/03/17 Срд 13:42:07  148326281
Ьамп
Аноним 08/03/17 Срд 13:42:25  148326294
Ьамп
Аноним 08/03/17 Срд 13:42:41  148326302
Ьамп
Аноним 08/03/17 Срд 13:42:58  148326319
Ьамп
Аноним 08/03/17 Срд 13:43:17  148326332
Ьамп
Аноним 08/03/17 Срд 13:44:03  148326366
Ьамп
Аноним 08/03/17 Срд 13:44:47  148326399
Все идет к тому, что весь тред будет состоять из моих бампов
Аноним 08/03/17 Срд 13:45:03  148326412
Бамп
Аноним 08/03/17 Срд 13:45:41  148326430
Бамп
Аноним 08/03/17 Срд 13:45:59  148326441
Ьамп
Аноним 08/03/17 Срд 13:46:17  148326452
Бамп
Аноним 08/03/17 Срд 13:46:33  148326468
Ьамрэп
Аноним 08/03/17 Срд 13:47:17  148326508
пмаБ
м
а
Б
Аноним 08/03/17 Срд 13:47:41  148326528
Ьаип
Аноним 08/03/17 Срд 13:48:07  148326550
Бааамп
а
а
а
м
п
Аноним 08/03/17 Срд 13:48:26  148326561
б а а а м п
а
а
а
м
п
Аноним 08/03/17 Срд 13:48:54  148326584
п м а б
м
а
б
Аноним 08/03/17 Срд 13:49:39  148326625
Бамп
Аноним 08/03/17 Срд 13:49:56  148326647
Бамп
Аноним 08/03/17 Срд 13:50:27  148326665
У меня еще дохуя времени
Аноним 08/03/17 Срд 13:51:54  148326731
Чё-т я не могу в твою задачу въехать.
> 2. Тот же граф, но пара (9, 7). Программа должна вывести 0, т.к. нету такого пути из 9 в 7, чтобы он проходил постоянно по одной и той же вершине(точка сочленения есть, но вершины такой нет, так что можно сказать, что это частный случай).

вершина 1 же сочленение. Или нужно не сочленения всего графа считать, а сочленения графа, получающегося из путей от вершины к вершине?
Аноним 08/03/17 Срд 13:52:49  148326777
По сути нужно найти срез между двумя точками, яб гланул алгоритмы те и от них скакал. Удачи.
Аноним 08/03/17 Срд 13:53:30  148326809
>>148326731
>Для каждой описанной пары выведите на отдельной строке единственное число --- количество вершин c, таких, что любой путь из ai в bi, проходит через c
Вот вопрос в оригинале. Я сделал вывод, что это точки сочленения.
Аноним 08/03/17 Срд 13:54:23  148326848
>>148326731
>а сочленения графа, получающегося из путей от вершины к вершине?
Именно это
Аноним 08/03/17 Срд 13:56:21  148326926
>>148326777
Какие алгоритмы?
Аноним 08/03/17 Срд 13:56:43  148326939
Ьамп
Аноним 08/03/17 Срд 13:57:14  148326963
Уже 30 постов, обсуждение идет полным ходом
Аноним 08/03/17 Срд 13:59:32  148327054
WitchesNoPantie[...].jpg (257Кб, 1349x1900)
Если я правильно понял твою задачу, то я бы делал так:
1. Нашел поиском в глубину 1й путь, сохранил его в отдельный массив вершин-кандидатов в сочленения.
2. Продолжаю искать другие пути поиском с возвратом. Каждый найденный путь сличаю с массивом вершин-кандидатов. Из массива вершин-кандидатов удаляю вершины, которых нет в найденном пути.
3. Когда все возможные пути пройдены, массив вершин-кандидатов в сочленения становится массивом сочленений и его размер - искомая величина.
Аноним 08/03/17 Срд 14:06:47  148327430
>>148327054
Звучит неплохо, но:
Я не указал в ограничение 400 вершин. Работать твой алгоритм будет супер долго, тогда уже лучше завести массив, где будем записывать количество вхождений в эту вершину. Но тут опять же, нужно дохрена раз пускать поиск в глубину, и нужно как то различать пути между собой, короче это не то решение
Аноним 08/03/17 Срд 14:07:05  148327452
>>148325445 (OP)
На региональном этапе ВСОШ в этом году было подобное. Жопа моя чует, что нужно сделать некоторое подобие конденсации графа. Вершинами нового графа будут компоненты, на которые распадётся граф при удалении всех точек сочленения (пустые компоненты тоже считаются, т.е. на оппике между 1 и 2 тоже будет компонента) . Рёбрами будут точки сочленения, соединяющие эти компоненты. Думаю, за пару ДФСов это вполне возможно получить.
Дальше тупо находишь флойдом длины путей между каждыми двумя вершинами, и отвечаешь на запросы за О(1).

Особо не вдумывался, мог соврать.
Аноним 08/03/17 Срд 14:07:48  148327507
доебывается до [...].webm (3879Кб, 1280x720, 00:00:25)
Аноним 08/03/17 Срд 14:10:49  148327703
azLboEK460sav1.gif (1122Кб, 460x259)
>>148327430
Тогда проще.
Убираем из графа одну вершину и ищем путь любым способом.
Если не нашли - это вершина-сочленение.
Повторить для всех вершин графа.
Чё-т сильно сомневаюсь, что можно как-то принципиально быстрее это сделать.
Аноним 08/03/17 Срд 14:15:02  148327963
>>148327703
Ты мне сейчас рассказал, как искать точки сочленения. Для этого уже есть алгоритм, лучше ответь мне как путь "вычленить"
Аноним 08/03/17 Срд 14:16:56  148328063

>У меня еще дохуя времени
Ну дак сегодня не надо в школу идти
Аноним 08/03/17 Срд 14:16:58  148328067
>>148327452
>конденсация
>пустые компоненты
Звучит слишком сложно, я еще не настолько продвинутый. Эту задачу можно решить проще
Аноним 08/03/17 Срд 14:17:32  148328092
>>148328063
Эт да))))))))хд
Аноним 08/03/17 Срд 14:17:48  148328112
Бамп
Аноним 08/03/17 Срд 14:18:11  148328130
Ба п
Аноним 08/03/17 Срд 14:18:21  148328145
2014-10-19.jpg (28Кб, 604x445)
>>148327963
Так тебе же и нужны точки сочленения, только не всего графа, а для твоей пары. Т.е. тебе и надо точки сочленения найти, просто в процессе поиска проверять не весь граф на связность, а лишь связность данных тебе точек.
Аноним 08/03/17 Срд 14:20:36  148328264
IMG201703021452[...].jpg (7270Кб, 2592x4608)
Аноним 08/03/17 Срд 14:21:11  148328289
>>148328145
Не конкретно это точки, а ПУТЬ между ними
Аноним 08/03/17 Срд 14:21:44  148328318
ЬамЬ
Аноним 08/03/17 Срд 14:22:27  148328359
БАаааааааааа
Аноним 08/03/17 Срд 14:22:43  148328370
Бамп
Аноним 08/03/17 Срд 14:23:08  148328388
Бамп
Аноним 08/03/17 Срд 14:24:02  148328443
Бамп
Аноним 08/03/17 Срд 14:24:49  148328495
Бамп
Аноним 08/03/17 Срд 14:27:29  148328632
Бамп
Аноним 08/03/17 Срд 14:27:50  148328654
Бамп
Аноним 08/03/17 Срд 14:28:07  148328672
Бааааааааааааааааааааааааамп
Аноним 08/03/17 Срд 14:28:32  148328701
4892ccbed547544[...].jpg (139Кб, 1129x916)
Буду картинами бампать хз
Аноним 08/03/17 Срд 14:31:27  148328878
14870166754370s.jpg (2Кб, 220x123)
Бамп
Аноним 08/03/17 Срд 14:32:05  148328921
14886439809270.jpg (333Кб, 1920x1200)
Бамп
Аноним 08/03/17 Срд 14:32:24  148328939
Screenshot2017-[...].png (372Кб, 1920x1080)
Бамп
Аноним 08/03/17 Срд 14:33:11  148328976
14886680437710.jpg (66Кб, 604x403)
Аноним 08/03/17 Срд 14:33:57  148329021
>>148325445 (OP)
КАК ОТКЛЮЧИТЬ ЭТО ГОВНО!!11 АБУ ВЕРНИ ДВАЧ ГЛАЗА КРОВОТОЧАТ СУКА
Аноним 08/03/17 Срд 14:34:51  148329064
>>148328701
Брат, как отрубить подскажи, я тебе с дискреткой помогу.
Аноним 08/03/17 Срд 14:35:09  148329083
Умеренно аутичный вариант (графы не ебал лет пять) такой: а почему бы тебе не, скажем, взять поиск в глубину; запомнить, какой там путь у тебя нашёлся; а затем попробовать поискать маршруты из точек, соединенных с, скажем, начальной -- и глядеть, что там у тебя в маршрутах. Как только есть маршрут, соединяющий твои А и В без прохода по какой-то точке массиве первичного пути -- эту точку выкидываешь нахуй?
Аноним 08/03/17 Срд 14:42:35  148329509
1488973349778.jpg (4333Кб, 2592x4608)
Бамп
Аноним 08/03/17 Срд 14:44:26  148329649
>>148325445 (OP)
import java.io.BufferedReader;
import java.io.InputStream;
import java.util.;

class Pair<T, M> {
private final T first;
private final M second;

// конструктор
private Pair(T value1, M value2) {
this.first = value1;
this.second = value2;
}

// получить первый эл-т пары
public T getFirst() {
return this.first;
}

// получить второй эл-т пары
public M getSecond() {
return this.second;
}

// equals
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;

Pair<?, ?> pair = (Pair<?, ?>) obj;

if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
return !(second != null ? !second.equals(pair.second) : pair.second != null);

}

// hashcode
@Override
public int hashCode() {
int result = first != null ? first.hashCode() : 0;
result = 31
result + (second != null ? second.hashCode() : 0);
return result;
}

// конструктор
public static <T, M> Pair of(T value1, M value2) {
return new Pair(value1, value2);
}
}

class Graph {
private int V; // No. of vertices
private LinkedList<Integer> adj[]; // Array of lists for Adjacency List Representation
int time = 0;
static final int NIL = -1;

// Constructor
Graph(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; ++i)
adj = new LinkedList();
}

//Function to add an edge into the graph
void addEdge(int v, int w) {
adj[v].add(w); // Add w to v's list.
adj[w].add(v); //Add v to w's list
}

// A recursive function that find articulation points using DFS
// u --> The vertex to be visited next
// visited[] --> keeps tract of visited vertices
// disc[] --> Stores discovery times of visited vertices
// parent[] --> Stores parent vertices in DFS tree
// ap[] --> Store articulation points
void APUtil(int u, boolean visited[], int disc[],
int low[], int parent[], boolean ap[]) {

// Count of children in DFS Tree
int children = 0;

// Mark the current node as visited
visited = true;

// Initialize discovery time and low value
disc = low = ++time;

// Go through all vertices adjacent to this
Iterator<Integer> i = adj.iterator();
while (i.hasNext()) {
int v = i.next(); // v is current adjacent of u

// If v is not visited yet, then make it a child of u
// in DFS tree and recur for it
if (!visited[v]) {
children++;
parent[v] = u;
APUtil(v, visited, disc, low, parent, ap);

// Check if the subtree rooted with v has a connection to
// one of the ancestors of u
low = Math.min(low, low[v]);

// u is an articulation point in following cases

// (1) u is root of DFS tree and has two or more chilren.
if (parent == NIL && children > 1)
ap = true;

// (2) If u is not root and low value of one of its child
// is more than discovery value of u.
if (parent != NIL && low[v] >= disc)
ap = true;
}

// Update low value of u for parent function calls.
else if (v != parent)
low = Math.min(low, disc[v]);
}
}

void findCutPoints() {
// Mark all the vertices as not visited
boolean visited[] = new boolean[V];
int disc[] = new int[V];
int low[] = new int[V];
int parent[] = new int[V];
boolean ap[] = new boolean[V]; // To store articulation points

// Initialize parent and visited, and ap(articulation point)
// arrays
for (int i = 0; i < V; i++) {
parent = NIL;
visited = false;
ap = false;
}

// Call the recursive helper function to find articulation
// points in DFS tree rooted with vertex 'i'
for (int i = 0; i < V; i++)
if (visited == false)
APUtil(i, visited, disc, low, parent, ap);

// Now ap[] contains articulation points, print them
for (int i = 0; i < V; i++)
if (ap == true)
System.out.print(i + " ");
}
}

public class Main {

public static void main(String[] args) {
// a set of vertices
Set<Integer> vertices = new HashSet<>();
// a list of edges
List<Pair<Integer, Integer>> edges = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int start = scanner.nextInt();
int end = scanner.nextInt();
// adding those to the set of vertices
vertices.add(start);
vertices.add(end);
// making a pair, adding it to the list of edges
Pair<Integer, Integer> edge = Pair.of(start, end);
edges.add(edge);
}

Graph graph = new Graph(vertices.size());
for (int i = 0; i < edges.size(); i++) {
int a = edges.get(i).getFirst();
int b = edges.get(i).getSecond();
graph.addEdge(a, b);
}
graph.findCutPoints();
}
}
Вот это говно ищет все точки сочленения в графе, по идее из них можешь вытащить те, которые нужны под конкретную пару вершин. Ну или просто изначально такой подграф на вход давай.А теперь помоги мне избавиться от этого вырвиглазного говна, анончик, я в ахуе блядь, абу совсепм похеал нахуй.
Аноним 08/03/17 Срд 14:47:28  148329848
>>148325445 (OP)
>С нахождением точек сочленения проблем нет, но я не знаю, как вычленить из граф
Бля, ты уверен, что правильно хадание понял? Для 7 и 9 будет 0. ЛЮБОЙ путь должен проходить.
Аноним 08/03/17 Срд 14:51:08  148330111
http://e-maxx.ru/algo/bridge_searching
Аноним 08/03/17 Срд 14:51:13  148330117
14879768597732.jpg (172Кб, 999x750)
>>148325445 (OP)
Разберись в теории немного. Есть такая штука, как граф блоков и точек сочленения. Если ты сможешь его построить по исходному графу, то задача сильно упростится. Для ответа на запрос тебе достаточно будет найти расстояние между блоками данных вершин в построенном графе, а такие расстояния ты уже можешь эффективно предпосчитать. Тут, правда, есть один тонкий момент: если одна из данных вершин сама является точкой сочленения, то ответ на запрос немного усложняется, т.к. она находится в нескольких блоках.
Аноним 08/03/17 Срд 15:09:47  148331264
>>148325445 (OP)
А, лол так ты это изначально и нашёл. Ебучий зелёный дихайн. Короче, сначала находишь т.очки сочленения, потом удаляешь их из исходного графа и смотришь на свои вершины: если они в одной компоненте связности, то ответ 0, если в разных, то кол-во точек сочл, потому что точка солченения по определению
Пусть вершина v принадлежит некоторым блокам A и B. Вершине v инцидентны некоторые ребра e=uv \in A и f=wv \in B. Ребра e и f находятся в различных блоках, поэтому не существует двух непересекающихся путей между их концами. Учитывая, что один из путей между концами - путь из v в эту же вершину, получаем, что любой путь, соединяющий u и w, пройдет через v. При удалении v между u и w не останется путей, и одна из компонент связности распадется на две.
Типа того. Короче, как-то так. КАК УБРАТЬ ЕБУЧИЙ ЗЕЛЁНЫЙ ДИЗААЙН АААА
Аноним 08/03/17 Срд 15:11:38  148331394
Бля чуваки гости пришли, дико извиняюсь, что не могу всем ответить, энивей спасибо, за ваши объяснения

[Назад][Обновить тред][Вверх][Каталог] [Реквест разбана] [Подписаться на тред] [ ] 72 | 13 | 10
Назад Вверх Каталог Обновить

Топ тредов
Избранное