图论12-无向带权图及实现

文章目录

带权图

1.1带权图的实现

在无向无权图的基础上,增加边的权。

使用TreeMap存储边的权重。

  • 遍历输入文件,创建TreeMap adj存储每个节点。
  • 每个输入的adj节点链接新的TreeMap,存储相邻的边和权重
c 复制代码
private TreeMap<Integer, Integer>[] adj;

adj = new TreeMap[V];

for(int i = 0; i < V; i ++)
    adj[i] = new TreeMap<Integer, Integer>();
  • 两条边相连,则分别把权重加入各自的邻接表中
c 复制代码
adj[a].put(b, weight);
adj[b].put(a, weight);
  • 判断两点之间是否有边
c 复制代码
public boolean hasEdge(int v, int w){
    validateVertex(v);
    validateVertex(w);
    return adj[v].containsKey(w);
}
  • 求相邻的所有节点
c 复制代码
public Iterable<Integer> adj(int v){
    validateVertex(v);
    return adj[v].keySet();
}
  • 求两点的权值
c 复制代码
public int getWeight(int v, int w){

    if(hasEdge(v, w)) return adj[v].get(w);
    throw new IllegalArgumentException(String.format("No edge %d-%d", v, w));
}
  • 移除边
c 复制代码
public void removeEdge(int v, int w){
    validateVertex(v);
    validateVertex(w);
    if(adj[v].containsKey(w)) E --;
    adj[v].remove(w);
    adj[w].remove(v);
}
  • 复制一个图
c 复制代码
public Object clone(){

    try{
        WeightedGraph cloned = (WeightedGraph) super.clone();
        cloned.adj = new TreeMap[V];
        for(int v = 0; v < V; v ++){
            cloned.adj[v] = new TreeMap<Integer, Integer>();
            for(Map.Entry<Integer, Integer> entry: adj[v].entrySet())
                cloned.adj[v].put(entry.getKey(), entry.getValue());
        }
        return cloned;
    }
    catch (CloneNotSupportedException e){
        e.printStackTrace();
    }
    return null;
}

1.2 完整代码

c 复制代码
package Chapter09_Weight_Graph;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.Scanner;


/// 暂时只支持无向带权图
public class WeightedGraph implements Cloneable{

    private int V;
    private int E;
    private TreeMap<Integer, Integer>[] adj;

    public WeightedGraph(String filename){

        File file = new File(filename);

        try(Scanner scanner = new Scanner(file)){

            V = scanner.nextInt();
            if(V < 0) throw new IllegalArgumentException("V must be non-negative");
            adj = new TreeMap[V];
            for(int i = 0; i < V; i ++)
                adj[i] = new TreeMap<Integer, Integer>();

            E = scanner.nextInt();
            if(E < 0) throw new IllegalArgumentException("E must be non-negative");

            for(int i = 0; i < E; i ++){
                int a = scanner.nextInt();
                validateVertex(a);
                int b = scanner.nextInt();
                validateVertex(b);
                int weight = scanner.nextInt();

                if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");
                if(adj[a].containsKey(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");

                adj[a].put(b, weight);
                adj[b].put(a, weight);
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }

    public void validateVertex(int v){
        if(v < 0 || v >= V)
            throw new IllegalArgumentException("vertex " + v + "is invalid");
    }

    public int V(){
        return V;
    }

    public int E(){
        return E;
    }

    public boolean hasEdge(int v, int w){
        validateVertex(v);
        validateVertex(w);
        return adj[v].containsKey(w);
    }

    public Iterable<Integer> adj(int v){
        validateVertex(v);
        return adj[v].keySet();
    }

    public int getWeight(int v, int w){

        if(hasEdge(v, w)) return adj[v].get(w);
        throw new IllegalArgumentException(String.format("No edge %d-%d", v, w));
    }

    public int degree(int v){
        validateVertex(v);
        return adj[v].size();
    }

    public void removeEdge(int v, int w){
        validateVertex(v);
        validateVertex(w);
        if(adj[v].containsKey(w)) E --;
        adj[v].remove(w);
        adj[w].remove(v);
    }

    @Override
    public Object clone(){

        try{
            WeightedGraph cloned = (WeightedGraph) super.clone();
            cloned.adj = new TreeMap[V];
            for(int v = 0; v < V; v ++){
                cloned.adj[v] = new TreeMap<Integer, Integer>();
                for(Map.Entry<Integer, Integer> entry: adj[v].entrySet())
                    cloned.adj[v].put(entry.getKey(), entry.getValue());
            }
            return cloned;
        }
        catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();

        sb.append(String.format("V = %d, E = %d\n", V, E));
        for(int v = 0; v < V; v ++){
            sb.append(String.format("%d : ", v));
            for(Map.Entry<Integer, Integer> entry: adj[v].entrySet())
                sb.append(String.format("(%d: %d) ", entry.getKey(), entry.getValue()));
            sb.append('\n');
        }
        return sb.toString();
    }

    public static void main(String[] args){

        WeightedGraph g = new WeightedGraph("gw1.txt");
        System.out.print(g);
    }
}
相关推荐
oier_Asad.Chen1 天前
【OI学习笔记】Floyed-Warshall算法解决传递闭包问题
c++·笔记·学习·算法·图论·最短路·传递闭包
依然鸣1 天前
蓝桥杯多校模拟赛(第二场)题解
数据结构·c++·经验分享·学习·算法·图论
wabs6661 天前
关于图论【Kruskal算法|卡码网53.寻宝的思考】
数据结构·算法·图论·卡码网
qz5zwangzihan14 天前
题解:Atcoder Beginner Contest abc469 F - GCD Maximum Spanning Tree
c++·图论·kruskal·并查集·atcoder·abc469·abc469_f
wabs6664 天前
关于图论【卡码网108.多余的边的思考】
数据结构·算法·图论
漂流瓶jz5 天前
UVA-12627 奇怪的气球膨胀 题解答案代码 算法竞赛入门经典第二版
算法·图论·递归·aoapc·算法竞赛入门经典·uva·12627
wabs6665 天前
关于图论【卡码网107.寻找存在的路线的思考】
数据结构·算法·图论
一条大祥脚6 天前
26杭电暑期第三场 DP|费用流|分解质因子|数论|贪心|图论|期望|无穷级数
网络·图论·网络流·无穷级数·费用流
wabs6667 天前
关于图论【卡码网105.有向图的完全联通的思考】
数据结构·算法·图论
wabs6668 天前
关于图论【卡码网110.字符串迁移的思考】
数据结构·算法·图论