每日总结 12.29

对Floyd-Warshall算法的简单学习

对Dijkstra算法的简单学习

首先是Floyd-Warshall算法

了解最短路径的两种基础算法

1.求一地到另一地的最短路径

法一便是Floyd-Warshall

#include<stdio.h>
int main()
{
	int e[10][10],k,i,j,n,m,t1,t2,t3;
	int inf=99999999;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(i==j)
			{
				e[i][j]=0;
			}
			else
			{
				e[i][j]=inf;
			}
		}
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&t1,&t2,&t3);
		e[t1][t2]=t3;
	}
	//Floyd Warshall核心算法
	for(k=1;k<=n;k++)
	{
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(e[i][j]>e[i][k]+e[k][j])
					e[i][j]=e[i][k]+e[k][j];
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			printf("%10d",e[i][j]);
		}
		printf("\n");
	}
	return 0;
}

另一种就是Dijkstra

#include<stdio.h>
int main()
{
	int e[10][10],dis[10],book[10],i,j,n,m,t1,t2,t3,u,v,min;
	int inf=99999999;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(i==j)e[i][j]=0;
			else e[i][j]=inf;
		}
	}
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&t1,&t2,&t3);
		e[t1][t2]=t3;
	}
	for(i=1;i<=n;i++)
	{
		dis[i]=e[1][i];
	}
	for(i=1;i<=n;i++)
	{
		book[i]=0;
	}
	book[1]=1;
	//Dijkstra算法核心
	for(i=1;i<=n-1;i++)
	{
		min=inf;
		for(j=1;j<=n;j++)
		{
			if(book[j]==0&&dis[j]<min)
			{
				min=dis[j];
				u=j;
			}
		}
		book[u]=1;
		for(v=1;v<=n;v++)
		{
			if(e[u][v]<inf)
			{
				if(dis[v]>dis[u]+e[u][v])
				{
					dis[v]=dis[u]+e[u][v];
				}
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		printf("%d ",dis[i]);
	}    
	getchar();
	getchar();
	return 0;
}

Floyd-Warshall的时间复杂度是n的3次方

而Dijkstra的时间复杂度为(M+N)logN相比于前一种更加简便某种意义上更快并且空间复杂度也比较低但是不能解决负权

                                       单词接龙

注意:本题为上古 NOIP 原题,不保证存在靠谱的做法能通过该数据范围下的所有数据。

题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast 和 astonish,如果接成一条龙则变为 beastonish,另外相邻的两部分不能存在包含关系,例如 at 和 atide 间不能相连。

输入格式

输入的第一行为一个单独的整数 nn 表示单词数,以下 nn 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。

输出格式

只需输出以此字母开头的最长的“龙”的长度。

输入输出样例

输入 #1复制

5
at
touch
cheat
choose
tact
a

输出 #1复制

23

说明/提示

样例解释:连成的“龙”为 atoucheatactactouchoose

n \le 20n≤20。

 代码如下

#include<stdio.h>
#include<string.h>
char s[21][100],p[1000],tou;
int n,book[21],len;
int find(char a[],char b[])
{
	int i,j,k,flag=0;
	for(i=strlen(a)-1;i>=0;i--)
	{
		k=i;
		for(j=0;a[k]&&b[j]&&b[j]==a[k];k++,j++);
		if(a[k]==0&&flag==0) 
		{
			flag=1;
		}
		else if(a[k]!=0&&flag==1) 
		{
			break;
		}
	}
	if(i<0) return 0;
	else return strlen(a)-k-1;
}
int dfs(char p[],int l)
{
	int i,k;
	char t[1000];
	strcpy(t,p);
	if(strlen(p)==0)
	{
		for(i=0;i<n;i++)
		{
			if(s[i][0]==tou) 
			{
				strcpy(t,s[i]);
				if(len<strlen(s[i])) 
				{
					len=strlen(s[i]);
				}
				book[i]++;
				dfs(s[i],strlen(s[i]));
				book[i]--;
			}
		}
	}
	else 
		for(i=0;i<n;i++)
	{
		k=find(p,s[i]);
		if(k&&book[i]<2)
		{
			if(len<l+strlen(s[i])-k)
			{
				len=l+strlen(s[i])-k;
			}
			book[i]++;
			dfs(s[i],l+strlen(s[i])-k);
			book[i]--;
		}
	}
}
int main()
{
	int i;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%s\n",s[i]);
	}
	scanf("%c",&tou);
	dfs(p,0);
	printf("%d\n",len);
	return 0;
}

对昨天学习的进行巩固dfs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值