对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