0
点赞
收藏
分享

微信扫一扫

2.14日学习总结

朱小落 2022-02-14 阅读 59

今天接着做最短路的题解。 之前做的题目都是单向图。今天做一个双向图的题目。 还有一个要经过两次函数的题目。 题目如下。

  

这个题目总的来说。 可以在模板题。那个代码的基础上进行稍微修改一下就可以解决了。 事实上绝大多数最短路的问题都可以依据这个模板进行修改。 我写的模板是有向图的。 然后如果是无相图的话。我采取的方法是输入一个相反的方向的路线存进数组中。如此就可以解决这个问题的。

 具体代码就是如下,

#include<bits/stdc++.h> 
using namespace std;
int head[10000000],cnt;
long long ans[1000000];
int vis[1000000];
int m,n,s,t;
struct a
{
	int to;
	int next1;
	int fee;
}a[1000000];
void b1(int x,int y,int z)
{
	a[++cnt].to=y;
	a[cnt].fee=z;
	a[cnt].next1=head[x];
	head[x]=cnt;
}
int main()
{
	cin>>m>>n>>s>>t;
	for(int i=1;i<=n;i++)
	{
		ans[i]=2147483647;
	}
	ans[s]=0;
	for(int i=1;i<=n;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		b1(a,b,c);
		b1(b,a,c);
	}
	int s1=s;
	while(vis[s1]==0)
	{
		long long minn=2147483647;
		vis[s1]=1;
		for(int i=head[s1];i!=0;i=a[i].next1)
		{
			if(vis[a[i].to]==0&&ans[a[i].to]>ans[s1]+a[i].fee)
			{
				ans[a[i].to]=ans[s1]+a[i].fee;
			}
		}
		for(int i=1;i<=m;i++)
		{
			if(ans[i]<minn&&vis[i]==0)
			{
				minn=ans[i];
				s1=i;
			}
		}
	}
 
		cout<<ans[t]<<' ';
		
}

  然后就是另外一题了。 这个题有一点点恶心的地方。先看题目吧。

 这个题目恶心的地方就在于他不仅有一个一到多,还有一个多到一。 然后我就利用了一个反向图。来将多到一转化成了一到多,原理就是,如以下这个例子,由c到a的路径为,C到b到a,存到反向图里的话。就会变成ab,这样的话,在反向图中a到c点的最短途径,就是c到a的最短途径。

但是现在就要写两次dijkstra,然后就会有巨大的代码量和调试过程。反正当时是。弄得我怀疑人生。 具体的代码就是下面这个一百多行的。

#include<bits/stdc++.h> 
using namespace std;
int head[10000000]={0},cnt=1;
long long ans[1000000];
int vis[1000000];
int m,n;
int head1[10000000]={0},cnt1=1;
long long ans1[1000000];
int vis1[1000000];
int m1,n1;
struct a
{
	int to;
	int next1;
	int fee;
}a[1000000] ,a1[1000000];
void b1(int x,int y,int z)
{
	a[++cnt].to=y;
	a[cnt].fee=z;
	a[cnt].next1=head[x];
	head[x]=cnt;
}
void b2(int x,int y,int z)
{
	a1[++cnt1].to=y;
	a1[cnt1].fee=z;
	a1[cnt1].next1=head1[x];
	head1[x]=cnt1;
}
int main()
{
	cin>>m>>n;
	for(int i=2;i<=n;i++)
	{
		ans[i]=2147483647;
		ans1[i]=2147483647;
		
	}
	ans[1]=0;
	ans1[1]=0;
	for(int i=1;i<=n;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		b1(a,b,c);
		b2(b,a,c);
	}
	int s1=1;
	while(vis[s1]==0)
	{
		long long minn=2147483647;
		vis[s1]=1;
		for(int i=head[s1];i!=0;i=a[i].next1)
		{
			if(vis[a[i].to]==0&&ans[a[i].to]>ans[s1]+a[i].fee)
			{
				ans[a[i].to]=ans[s1]+a[i].fee;
			}
		}
		for(int i=2;i<=m;i++)
		{
			if(ans[i]<minn&&vis[i]==0)
			{
				minn=ans[i];
				s1=i;
			}
		}
	}
    int s2=1; 
		while(vis1[s2]==0)
		{
			long long minn=2147483647;
			vis1[s2]=1;
			for(int i=head1[s2];i!=0;i=a1[i].next1)
			{
				if(vis1[a1[i].to]==0&&ans1[a1[i].to]>ans1[s2]+a1[i].fee)
				{
					ans1[a1[i].to]=ans1[s2]+a1[i].fee;
				}
			}
			for(int i=2;i<=m;i++)
			{
				if(ans1[i]<minn&&vis1[i]==0)
				{
					minn=ans1[i];
					s2=i;
				}
			}
		}
		 long long int f=0;
	for(int i=2;i<=m;i++)
	{
		f=f+ans[i]+ans1[i];
	 
	}
	 cout<<f;
	 
}

好了,今天的学习总结就到这里了。

举报

相关推荐

2.14总结

2.17日学习总结

2.9日学习总结

1.20日学习总结

1.18日学习总结

1.19日学习总结

1月23日学习总结

0 条评论