图论简单代码模板(Matlab)

1.dijstra
求起点到其他城市最短路:

pb(i)=1/0(当第i顶点的标号已/未成为P标号)

index1(i)存储标号顶点顺序

index2(i)存放始点到第i顶点最短通路中第i顶点前一顶点的序号

d(i)存放从始点到第i顶点最短通路的值

clc,clear
a=zeros(6);
a(1,2)=50;a(1,4)=40;
...
%用于初始化边权

a=a+a';
a(a==0)=inf;
pb(1:length(a))=0;pb(1)=1;index1=1;index2=ones(1,length(a));
d(1:length(a))=inf;d(1)=0;
temp=1;%最新的P标号的顶点

while sum(pb)<length(a)
   tb=find(pb==0);
   d(tb)=min(d(tb),d(temp)+a(temp,tb));
   tmpb=find(d(tb)==min(d(tb)));
   temp=tb(tmpb(1));%可能有多个点同时达到最小值,取其中一个
   pb(temp)=1;
   index1=[index1,temp];
   temp2=find(d(index1)==d(temp)-a(temp,index1));
   index2(temp)=index1(temp2(1));
end
d,index1,index2

2.SPFA实现最小费用最大流

clear
V =[
     0     5     8     0     0
     0     0     0     3     4
     0     2     0    10     0
     0     0     0     0     8
     0     0     0     0     0
     ]; %volume
C =[
     0     8     7     0     0
     0     0     0     2     9
     0     5     0     9     0
     0     0     0     0     4
     0     0     0     0     0
     ]; %cost
n=size(V,2);
wf=0;wf0=inf;
f=zeros(n,n);
while 1
    a=inf*(ones(n,n)-eye(n,n));
    for i=1:n
        for j=1:n
            if V(i,j)>0&&f(i,j)==0
                a(i,j)=C(i,j);
            elseif V(i,j)>0&&f(i,j)==V(i,j)
                a(j,i)=-C(i,j);
            elseif V(i,j)>0
                a(i,j)=C(i,j);a(j,i)=-C(i,j);
            end
        end
    end
    
    %SPFA
    p=inf*ones(1,n);
    p(1)=0;
    s=1:n;
    s(1)=0;
    for k=1:n
        pd=1;
        for i=2:n
            for j=1:n
                if p(i)>p(j)+a(j,i)
                    p(i)=p(j)+a(j,i);
                    s(i)=j;
                    pd=0;
                end
            end
        end
        if pd
            break;
        end
    end
    if p(n)==Inf
        disp('completed');
    end
    
    %adjustment
    k=n;dvt=inf;t=n;%dvt:the amount of dvt
    while 1
        if a(s(t),t)>0
            dvtt=V(s(t),t)-f(s(t),t);
        elseif a(s(t),t)<0
            dvtt=f(s(t),t);
        end
        if dvt>dvtt
            dvt=dvtt;
        end
        if s(t)==1
            break;
        end
        t=s(t);
    end
    pd=0;
    if wf+dvt>=wf0
       dvt=wf0-wf;
       pd=1;
    end
    t=n;
    while 1
        if a(s(t),t)>0
            f(s(t),t)=f(s(t),t)+dvt;
        elseif a(s(t),t)<0
            f(s(t),t)=f(s(t),t)-dvt;
        end
        if(s(t)==1)
            break;
        end
        t=s(t);
    end
    if pd
        break;
    end
end

wf=sum(f(1,:));
zwf=sum(sum(C.*f));

f
wf
zwf
        
    
        
    

3.模板dinic

function:

function [f,Maxflow] = maxflow(C)

[row,colomn]=size(C);
s=1;t=colomn;
f=zeros(row);
maxflow=0;
while 1
    vis=[];
    vis=[vis s];
    queue_head=s;
    queue_tail=s;
    queue=zeros(1,row);%队列当作存放节点的容器
    queue(queue_head)=s;
    queue_head=queue_head+1;
    per=zeros(1,row);%表示每个节点的前驱节点
    per(s)=s;
    while queue_head~=queue_tail
        pos=queue(queue_tail);
        for nxt=1:row
            if C(pos,nxt)-f(pos,nxt)>0 && isempty(find(vis==nxt,1))
                queue(queue_head)=nxt;
                queue_head=queue_head+1;
                vis=[vis nxt];
                per(nxt)=pos;
            end
        end
        queue_tail=queue_tail+1;
    end
    if per(t)==0%无法到达汇点
        break;
    end
    
    %从汇点反向出发到达源点
    path=[];
    pos_tmp=row;
    e_cnt=0;%记录经过的边数
    while pos_tmp~=s
        if C(per(pos_tmp),pos_tmp)-f(per(pos_tmp),pos_tmp)>0
            e_val=C(per(pos_tmp),pos_tmp)-f(per(pos_tmp),pos_tmp);
            path=[path;per(pos_tmp) pos_tmp e_val 1];%建正向边
            pos_tmp=per(pos_tmp);
        end
        if C(pos_tmp,per(pos_tmp))-f(pos_tmp,per(pos_tmp))>0
            e_val=C(pos_tmp,per(pos_tmp))-f(pos_tmp,per(pos_tmp));
            path=[path;pos_tmp per(pos_tmp) e_val -1];%建反向边
            pos_tmp=per(pos_tmp);
        end
        
        e_cnt=e_cnt+1;
    end
    
    min_val=min(path(:,3));
    max_flow=max_flow+min_val;
    for pos=1:e_cnt
        if path(pos,4)==1
            f(path(pos,1),path(pos,2))=f(path(pos,1),path(pos,2))+min_val;
        end
        if path(pos,4)==-1
            f(path(pos,2),path(pos,1))=f(path(pos,2),path(pos,1))-min_val;
        end
    end
end


posted @   SxtoxA  阅读(157)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
12 13
点击右上角即可分享
微信分享提示