algorithm - 给定圆上图的节点,找到要删除的最小节点数以获得一个图,其中每个节点都有到下一个节点的边
问题描述
给定n个人坐在桌旁,其中一些人彼此熟悉,熟悉度是双向关系,求最少要从桌子上淘汰的人,才能有一张桌子上每个人都熟悉的桌子邻居。给出 O(n^2) 的解
我目前的努力:正如订单所示,我尝试通过 T(n) = T(n-1) + O(n) 来解决问题,但是如果我认为我已经找到了包含 m 个节点的理想圆,现在我想添加一个新节点,我检查新节点是否可以成为圈子的新成员并创建 m+1 个节点的新圈子,如果可以,则问题已解决,但如果不是,我确实需要存储所有长度为 m-1, m-2,... 的圆圈,并将这个新节点添加到它们,这需要超过 O(n) 时间。
解决方案
假设我们有一个带有n
节点的图,0 to n - 1
。
如果我们将问题视为找到从节点 A 回到 A 的最短循环,则节点a
和之间的距离b
是绝对不同的(b - a - 1)
(即这两者之间的所有节点),我们只能从a
到b
如果b > a
或者a
是起始节点。这个问题被简化为经典的在图中寻找最短路径。
使用 Dijkstra 算法,我们可以获得 O(N^2 log N) 算法。
Java代码:
class State{
int node, distance;
}
int result = n - 1;
for(int i = 0; i < n; i++){
//Find the shortest path to move from i -> i
PriorityQueue<State> q = new PriorityQueue<>((a , b) -> Integer.compare(a.distance, b.distance));
for(int j : map[i]) {
if( j > i){
q.add(new State(j , j - i + 1);
}
}
int[]dist = new int[n];
Arrays.fill(dist, n - 1);
while(!q.isEmpty()){
State s = q.poll();
if(s.distance != dist[s.node]){
continue;
}
for(int j : map[s.node]){
if((j > s.node || j == i) && dist[j] > s.distance + (j - s.node + 1)){
dist[j] = s.distance + (j - s.node + 1);
q.add(new State(j, dist[j]);
}
}
}
result = Integer.min(result, dist[i]);
}
推荐阅读
- java - 如何在 MacOS 上修复 IntelliJ 中的 Javac2.home 值?
- reactjs - TypeError:无法读取未定义的属性“handleSelect”
- google-sheets - GoogleFinance:按月获取历史记录
- python - 获取“ValueError:'输出'必须在循环之前定义。” 拟合模型时出错
- python - 从原始数据帧执行计算和新数据帧
- java - 使用 build.xml 将行号添加到堆栈跟踪
- google-analytics-4 - Google Analytics 4 中 page_view 和 session_start 的区别
- ethereum - 如何在 web3Provider 中调用合约方法并用它发送值?
- azure-web-app-service - 部署使用 Microsoft bot 框架构建的 bot
- reactjs - Visual Studio 代码 - 使用 Tailwind JIT CSS 在保存时编译