图论 拓扑排序 最短路 的几个模板(Java)
Published on 2022-11-17 23:03 in 暂未分类 with 林动

图论 拓扑排序 最短路 的几个模板(Java)

    topsort

    	static boolean topsort()
    	{
    	    hh=0;tt=-1;
    	    for(int i=1;i<=n;++i)
    	    {
    	        if(d[i]==0)q[++tt]=i;
    	    }
    	    while(hh<=tt)
    	    {
    	        int t=q[hh++];
    	        for(int i=h[t];i!=-1;i=ne[i])
    	        {
    	            int j=e[i];
    	            d[j]--;
    	            if(d[j]==0)q[++tt]=j;
    	        }
    	    }
    	    if(tt==n-1)return true;
    	    return false;
    	}
    

    下面四个最短路算法里,只有bell_ford算法不需要st数组,后三个是迭代,判断是否存在最短路需要if(dist[n]>INF/2)来判断 ,spfa判断负环就多了两行,spfa和优先队列dijkstra很像

    朴素dijkstra

    	static void dijkstra(int u)
    	{
    	    Arrays.setAll(dist,x->INF);
    	    dist[u]=0;
    	    for(int i=0;i<n;++i)
    	    {
    	        int t=-1;
    	        for(int j=1;j<=n;++j)
    	        {
    	            if(st[j]==false&&(t==-1||dist[t]>dist[j]))t=j;
    	        }
    	        st[t]=true;
    	        for(int j=1;j<=n;++j)
    	        {
    	            if(dist[j]>dist[t]+g[t][j])dist[j]=dist[t]+g[t][j];
    	        }
    	    }
    	}
    

    优先队列dijkstra

    	static void dijkstra(int u)
    	{
    	    Arrays.setAll(dist,x->INF);
    	    dist[u]=0;
    	    PriorityQueue<pair> q=new PriorityQueue<pair>(new mcomp());
    	    q.offer(new pair(u,0));
    	    while(!q.isEmpty())
    	    {
    	        pair t=q.poll();
    	        for(int i=h[t.id];i!=-1;i=ne[i])
    	        {
    	            int j=e[i];
    	            if(dist[j]>t.w+w[i])
    	            {
    	                dist[j]=t.w+w[i];
    	                q.offer(new pair(j,dist[j]));
    	            }
    	        }
    	    
    
    c++版本
    void dijkstra2(int u)
    {
    	for(int i=1;i<=n;++i)dist[i]=INF;
    	dist[u]=0;
    	priority_queue<node> q;
    	q.push(node(u,0));
    	while(!q.empty())
    	{
    		node t=q.top();q.top();
    		if(st[t.id])continue;
    		st[t.id]=true;
    		for(int i=h[t.id];i!=-1;i=ne[i])
    		{
    			int j=e[i];
    			if(dist[j]>dist[t.id]+w[i])
    			{
    				dist[j]=dist[t.id]+w[i];
    				q.push(node(j,dist[j]));
    			}
    		}
    	}
    }
    

    bell_ford

    	static void bell_ford(int u)
    	{
    		Arrays.setAll(dist, x->INF);
    		dist[u]=0;
    		for(int i=0;i<k;++i)
    		{
    			backup=dist.clone();
    			for(int j=0;j<m;++j)
    			{
    				int a,b,w;
    				a=es[j].a;
    				b=es[j].b;
    				w=es[j].w;
    				dist[b]=Math.min(dist[b], backup[a]+w);
    			}
    		}
    	}
    
    if(dist[n]>INF/2)
    

    spfa

    	static void spfa(int u)
    	{
    		Arrays.setAll(dist, x->INF);
    		q.offer(u);
    		dist[u]=0;
    		st[u]=true;
    		while(!q.isEmpty())
    		{
    			int t=(int)q.poll();
    			st[t]=false;
    			for(int i=h[t];i!=-1;i=ne[i])
    			{
    				int j=e[i];
    				if(dist[j]>dist[t]+w[i])
    				{
    					dist[j]=dist[t]+w[i];
    					if(st[j]==false)
    					{
    						st[j]=true;
    						q.offer(j);
    					}
    				}
    			}
    		}
    	}
    
    
    if(dist[n]>INF/2)
    

    spfa判断负环

    	static Queue q=new LinkedList();
    	static boolean spfa()
    	{
    		for(int i=1;i<=n;++i){
    			st[i]=true;
    			q.offer(i);
    		}
    		while(!q.isEmpty())
    		{
    			int t=(int)q.poll();
    			st[t]=false;
    			for(int i=h[t];i!=-1;i=ne[i])
    			{
    				int j=e[i];
    				if(dist[j]>dist[t]+w[i])
    				{
    					dist[j]=dist[t]+w[i];
    					cnt[j]=cnt[t]+1;
    					if(cnt[j]==n)return true;
    					if(st[j]==false)
    					{
    					    q.offer(j);
    					    st[j]=true;
    					}
    				}
    			}
    		}
    		return false;
    	}
    

    floyd

    初始化,建图,算法,判断用if(dist[a][b]>INF/2)

    import java.util.*;
    
    public class Main
    {
    	static int n,m,k,N=205,INF=0x3f3f3f3f;
    	static int dist[][]=new int [N][N];
    	static void floyd()
    	{
    		for(int k=1;k<=n;++k)
    			for(int i=1;i<=n;++i)
    				for(int j=1;j<=n;++j)
    				{
    					dist[i][j]=Math.min(dist[i][j], dist[i][k]+dist[k][j]);
    				}
    	}
    	public static void main(String args[])
    	{
    		Scanner sc=new Scanner(System.in);
    		n=sc.nextInt();
    		m=sc.nextInt();
    		k=sc.nextInt();
    		for(int i=1;i<=n;++i)
    			for(int j=1;j<=n;++j)
    				if(i!=j)dist[i][j]=INF;
    		
    		for(int i=0;i<m;++i)
    		{
    			int a,b,c;
    			a=sc.nextInt();
    			b=sc.nextInt();
    			c=sc.nextInt();
    			dist[a][b]=Math.min(dist[a][b], c);
    		}
    		floyd();
    		for(int i=0;i<k;++i)
    		{
    			int a,b;
    			a=sc.nextInt();
    			b=sc.nextInt();
    			if(dist[a][b]>INF/2)System.out.println("impossible");
    			else
    			System.out.println(dist[a][b]);
    		}
    	}
    }
    
    posted @   林动  阅读(28)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 地球OL攻略 —— 某应届生求职总结
    · 周边上新:园子的第一款马克杯温暖上架
    · Open-Sora 2.0 重磅开源!
    · 提示词工程——AI应用必不可少的技术
    · .NET周刊【3月第1期 2025-03-02】
    点击右上角即可分享
    微信分享提示