Ex 3_25 图中每个顶点有一个相关价格..._十一次作业


(a)首先对有向无环图进行拓扑排序,再按拓扑排序的逆序依次计算每个顶点的cost值,每个顶点的cost值为自身的price值与相邻顶点间的cost值得最小值
(b)求出图中的每一个强连通分量,并把所有得强连通分量看成是一个有向无环图,设每一个强连通分量的price值为该强连通分量中顶点的最小的price值。然后再按(a)中的步骤处理DAG
package org.xiu68.ch03.ex11; import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack; public class Ex3_25 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] edges=new int[][]{
{0,0,1,0,0,0},
{0,0,0,1,0,0},
{0,0,0,0,1,1},
{0,0,0,0,1,1},
{0,0,0,0,0,0},
{0,0,0,0,0,0}
};
int[] price=new int[]{2,3,6,1,4,5};
MGraph2 m1=new MGraph2(edges, price);
m1.getCost();
System.out.println("*****************");
m1.getSccCost();
//输出
/*
cost[0]:2
cost[1]:1
cost[2]:4
cost[3]:1
cost[4]:4
cost[5]:5
*****************
cost[0]=2
cost[1]=1
cost[2]=4
cost[3]=1
cost[4]=4
cost[5]=5
*/
System.out.println("*******************");
int[][] edges1=new int[][]{
{0,0,0,0,0,0,0},
{1,0,0,1,0,0,0},
{1,0,0,1,0,0,0},
{0,0,0,0,1,1,0},
{0,0,0,1,0,0,1},
{0,0,0,1,0,0,1},
{0,0,0,0,1,1,0}
};
int[] price1=new int[]{6,7,9,5,3,4,2};
MGraph2 m2=new MGraph2(edges1, price1);
m2.getSccCost();
//输出
/*
cost[0]=6
cost[1]=2
cost[2]=2
cost[3]=2
cost[4]=2
cost[5]=2
cost[6]=2
*/
} } class MGraph2{
private int[][] edges; //有向图
private int[][] rEdges; //有向图的反向图
private int vexNum; //顶点数量
private int[] price; //每个顶点的相对价格
private int[][] sccEdges; //强连通分量(DAG)之间的关系
private Stack<Integer> stack; //存储反向图深度优先遍历的post值 public MGraph2(int[][] edges,int[] price){
this.edges=edges;
this.vexNum=edges.length;
this.price=price;
this.stack=new Stack<>();
this.rEdges=new int[vexNum][vexNum];
this.sccEdges=new int[vexNum][vexNum]; //求原图的反向图
for(int i=0;i<vexNum;i++){
for(int j=i+1;j<vexNum;j++){
rEdges[i][j]=edges[j][i];
rEdges[j][i]=edges[i][j];
}
}
} //**********************************************************
//针对有向无环图,获取每个顶点的cost值
public void getCost(){
ArrayDeque<Integer> queue=new ArrayDeque<Integer>(); //存取拓扑排序的逆序
int[] cost=new int[vexNum];
for(int i=0;i<vexNum;i++)
cost[i]=price[i];
topoSort(queue,edges,vexNum); //依次处理每个顶点,每个顶点取自身的price值和邻接点的cost值得最小值
while(!queue.isEmpty()){
int v=queue.poll();
for(int i=0;i<vexNum;i++){
if(edges[v][i]==1 && cost[i]<cost[v])
cost[v]=cost[i];
}
}
for(int i=0;i<vexNum;i++)
System.out.println("cost["+i+"]:"+cost[i]);
}
//求拓扑排序的逆序
public void topoSort(ArrayDeque<Integer> queue,int[][] edgeArray,int vertexNum){
boolean[] visited=new boolean[vertexNum];
for(int i=0;i<vertexNum;i++){
if(!visited[i])
topoDFS(queue,visited,edgeArray,vertexNum,i);
}
}
//深度优先遍历求拓扑排序
public void topoDFS(ArrayDeque<Integer> queue,boolean[] visited,int[][] edgeArray,int vertexNum,int v){
visited[v]=true;
for(int i=0;i<vertexNum;i++){
if(edgeArray[v][i]==1 && !visited[i]){
topoDFS(queue,visited,edgeArray,vertexNum,i);
}
}
queue.add(v);
} //****************************************************************
//针对所有有向图的情况,获取每个顶点的cost值
public void getSccCost(){
rDFSTraverse(); //先对反向图进行深度优先遍历 List<List<Integer>> sccs=new ArrayList<>(); //存放每一个强连通部件对应的顶点 boolean[] visited=new boolean[vexNum]; //记录深度优先遍历原图过程中非当前强连通分量已经访问的顶点
int[] visitedN=new int[vexNum]; //记录顶点属于第几个强连通分量
int n=0; //第几个强连通部件 for(int i=0;i<vexNum;i++){
visitedN[i]=-1;
} //依次出栈,并从该顶点开始对原图进行深度优先遍历,获取每个强连通分量对应的顶点
//并获取DAG之间的关系
while(!stack.isEmpty()){
int v=stack.pop();
if(!visited[v]){
sccs.add(new ArrayList<Integer>());
List<Integer> vexs=new ArrayList<>(); //获取第n个强连通分量的顶点 sccDFS(visited,visitedN,v,sccs,vexs,/*isSinkSCC,*/n);
//为了知道遍历第n个强连通分量之前已经访问过哪些顶点
//遍历完一个强连通分量再设visited值
for(int i=0;i<vexs.size();i++){
visited[vexs.get(i)]=true;
}
n++;
}
} int[] sccPrice=new int[sccs.size()];
int[] sccCost=new int[sccs.size()];
//将每个强连通分量的price值设为强连通分量中price值最小的顶点的price值
for(int i=0;i<sccs.size();i++){
sccPrice[i]=Integer.MAX_VALUE;
for(int j=0;j<sccs.get(i).size();j++){
//sccs.get(i).get(j) 第i个强连通分量的第j个顶点
if(price[sccs.get(i).get(j)]<sccPrice[i]){
sccPrice[i]=price[sccs.get(i).get(j)];
}
}
} //对DAG进行拓扑排序
ArrayDeque<Integer> topoQueue=new ArrayDeque<>();
topoSort(topoQueue, sccEdges, sccs.size()); for(int i=0;i<sccs.size();i++)
sccCost[i]=sccPrice[i]; //topoSort(topoQueue,edges,vexNum);
////依次处理DAG中每个顶点,每个顶点取自身的price值和邻接点的cost值得最小值
while(!topoQueue.isEmpty()){
int v=topoQueue.poll();
for(int i=0;i<sccs.size();i++){
if(sccEdges[v][i]==1 && sccCost[i]<sccCost[v])
sccCost[v]=sccCost[i];
}
} //visitedN[i] 第i个顶点在第几个强连通分量中
for(int i=0;i<vexNum;i++)
System.out.println("cost["+i+"]="+sccCost[visitedN[i]]);
} //对原图进行深度优先遍历
//在汇点强连通部件中对某个顶点进行深度优先遍历则刚好访问该强连通部件的所有顶点
private void sccDFS(boolean[] visited,int[] visitedN,int v,List<List<Integer>> sccs,
List<Integer> vexs,/*boolean[] isSinkSCC,*/int n){
sccs.get(n).add(v);
vexs.add(v);
visitedN[v]=n;
for(int i=0;i<vexNum;i++){
if(edges[v][i]==1){
//若遍历到其他强连通分量的顶点说明该强连通分量不是汇点强连通分量
if(visited[i]){
//i为其他强连通分量的顶点,所以当前强连通分量有一条边指向i所在的强连通分量
sccEdges[n][visitedN[i]]=1;
}else if(visitedN[i]!=n){
sccDFS(visited,visitedN,i,sccs,vexs,/*isSinkSCC,*/n);
}
}
}//for
}
//***********************************************************
/*
* 对反向图进行深度优先遍历,post值最大的顶点将位于反向图中的一个源点强连通部件,
* 也就是原图中的某个汇点连通部件的某个顶点
* 按post值从小到大,压入栈中
*/
public void rDFSTraverse(){
boolean[] visited=new boolean[vexNum];
for(int i=0;i<vexNum;i++){
if(!visited[i]){
rDFS(visited,stack,i);
}
}
}
//对反向图做深度优先遍历
private void rDFS(boolean[] visited,Stack<Integer> stack,int v){
visited[v]=true;
for(int i=0;i<vexNum;i++){
if(rEdges[v][i]==1 && !visited[i]){
rDFS(visited,stack,i);
}
}
stack.push(v);
}
}
Ex 3_25 图中每个顶点有一个相关价格..._十一次作业的更多相关文章
- Ex3_15 判断图是否是一个强连通分量 判断点是否在汇点强连通分量中_十一次作业
(a) 可以用图中的每一个顶点表示街道中的每个十字路口,由于街道都是单行的,所以图是有向图,若从一个十字路口都有一条合法的路线到另一个十字路口,则图是一个强连通图.即要验证的是图是否是一个强连通图. ...
- Swift 中使用 SwiftyJSON 制作一个比特币价格 APP
Swift 中处理 JSON 数据有很多种方式,可以使用原生的 NSJSONSerialization,也可以使用很多第三方库.原生的 NSJSONSerialization 方式这篇文章中介绍过.这 ...
- Ex 2_23 如果一个数组超过半数的元素都相同时,该数组被称为含有一个主元素..._第二次作业
将数组A划分为两个数组A1和A2 ,各含有A的一半元素或一半多一个.若A中含有主元素x,则A1和A2中至少有一个数组含有主元素x,对A1和A2递归地计算有无主元素,若A只含有一个元素,则A的主元素就是 ...
- Ex 2_16 给定一个无穷数组..._第二次作业
先比较数组的A[0]元素,若不相等接下来比较A[1],A[2],A[4],A[8]…,若找到一个区间A[2n-1]<x<A[2n],再对这个区间进行折半查找操作.总的时间为O(logn). ...
- _DataStructure_C_Impl:求图G中从顶点u到顶点v的一条简单路径
#pragma once #include<stdio.h> #include<stdlib.h> #define StackSize 100 typedef int Data ...
- javascript实现有向无环图中任意两点最短路径的dijistra算法
有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://w ...
- 【 D3.js 进阶系列 — 2.1 】 力学图的事件 + 顶点的固定
本章讨论在力学图中经常使用到的事件( Event ),然后对[p=555">进阶 - 第 2.0 章]的人物关系图进行改进.使用户可以固定拖拽的对象. 在[入门 - 第 9.2 章]和 ...
- Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离
Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离,既不是DFS搜索,也不是BFS搜索. 把Dijkstra 算法应用于无权图,或者所有边的权都相等的图,Dijkstra 算法等同于 ...
- 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记5——Direct3D中的顶点缓存和索引缓存
第12章 Direct3D绘制基础 1. 顶点缓存 计算机所描绘的3D图形是通过多边形网格来构成的,网网格勾勒出轮廓,然后在网格轮廓的表面上贴上相应的图片,这样就构成了一个3D模型.三角形网格是构建物 ...
随机推荐
- asp 调用 vb(activex dll) ,参数传递(传引用)需要注意
今天上午测试 vb 与 c(dll) 之间交互,传递参数的时候,没遇到什么太大的问题. 下午在asp中调用vb(activex dll)时, 在asp代码中传参数到 vb(dll)中时,遇到问题了. ...
- CodeBlocks: 生成的exe文件自定义一个图标
CodeBlocks生成的exe文件的图标默认是系统图标,如何自定义一个漂亮的小图标呢? 我是C菜鸟,平时只用CodeBlocks练习c,也不开发什么软件,这个问题就难倒我了. 到网上搜索了一下,发现 ...
- 一次有趣的ant-design与后端数据交互的使用
最近有个需求是新闻时间排序与点击量排序,数据库中存储的新闻是按照时间顺序排序的,从后台数据中取出数据,在前端进行页面展示即可. 我用到了ant-design中的Tabs切换页,样式大概如下图. 其实这 ...
- 2018.10.2浪在ACM 集训队第三次测试赛
2018.10.26 浪在ACM 集训队第三次测试赛 今天是暴力场吗???????可怕 题目一览表 来源 考察知识点 完成时间 A 1275 珠心算测试 NOIP 普及组 2014 暴力??? 201 ...
- echarts2 饼图处理标签文字过长使之达到指定字数换行的目的
在使用echarts2的过程中,有时会遇到标签文字过长导致显示不完整的问题.例如: 这时候就需要用到 标签里的formatter 回调函数来处理这种情况了. 方式一: formatter : ' { ...
- 博文中标题的样式H1H2H3H4
设置博文中标题的样式H1 设置博文中标题的样式H2 设置博文中标题的样式H3 设置博文中标题的样式H4 设置博文中标题的样式H5 设置博文中标题的样式H6
- IDEA下搜狗输入法输入中文时卡着不动的参考解决方法
在IntelliJ IDEA工具的java编辑窗口,给代码增加注释时发现,输入中文时,搜狗输入法界面不动,一直卡着,如图: 我想输入“根据”两个字,但搜狗输入法界面一直卡着不刷新,导致都不知道自己输 ...
- 继承之es5对比es6
es5: 熟悉es5的童鞋们就知道es5的继承多么恶心~~ es5最经典的继承写法就是如下这样 1.写一个function,用this来扩展其值类属性 2.prototype添加其方法类属性 3.若整 ...
- P1450 [HAOI2008]硬币购物
题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. di,s<=100000 ...
- 愉快且方便的处理时间-- LocalDate
java中做时间处理时一般会采用java.util.Date,但是相比于Date来说,还有更好的选择 -- java.time.LocalDate. 这是jdk8中新增的日期处理类,同时新增的还有ja ...