题意:
求一个图的最小环。
思路:
我们可以用floyd求也可以用dijkstra求,这里我两种方法都用了。
代码:
floyd
#include<cstdio>
#include<cstring>
int n,m,f[501][501],dis[501][501],a,b,c,ans;
int min(int x,int y){return x>y?y:x;}
int main()
{
for (int i=1;i<=500;i++)
for (int j=1;j<=500;j++)
f[i][j]=dis[i][j]=99999999;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
dis[a][b]=f[a][b]=c;
dis[b][a]=f[b][a]=c;
}
ans=2100000000;
for (int k=1;k<=n;k++)//边做floyd边求最小环
{
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)//i和j这里可以1~k-1,但1~n也没关系
if (dis[i][j]!=99999999&&f[j][k]!=99999999&&f[k][i]!=99999999)ans=min(ans,dis[i][j]+f[j][k]+f[k][i]);//dis[i][j]为i到j的最小距离
for (int i=1;i<=n;i++) //f[i][j]表示i到j这条边的长度,这样加起来就是一个环
for (int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);//floyd
}
if (ans==2100000000) printf("No solution");else
printf("%d",ans);
}
dijkstra
#include"cstdio"
#include"cstring"
int ans,k,min1,p,q,c[501],f[501][501],n,m,x,y,z,b[501];
int min(int x,int y) {return x>y?y:x;}
void dijkstra(int x,int y)
{
memset(b,0,sizeof(b));
for (int i=1;i<=n;i++) c[i]=f[x][i];
b[x]=1;c[x]=0;
for (int i=1;i<n;i++)
{
min1=99999999;
k=0;
for (int j=1;j<=n;j++)
if ((!b[j])&&(c[j]<min1))
{
min1=c[j];
k=j;
}
if (k==0) break;
b[k]=true;
for (int j=1;j<=n;j++)
if (c[k]+f[k][j]<c[j]) c[j]=c[k]+f[k][j];
}
}
int main()
{
scanf("%d%d",&n,&m);//dijkstra就是把i到j的边去掉,再用dijkstra求i到j的最小距离,再加上原来i到j的距离我们就可以形成了一个环,
memset(f,127/3,sizeof(f));//floyd比这个算法快
while (m--)
{
scanf("%d%d%d",&x,&y,&z);
f[x][y]=f[y][x]=z;
}
ans=99999999;
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
{
int temp=f[i][j];
f[j][i]=f[i][j]=99999999;//去掉边
dijkstra(i,j);//求最短距离
f[j][i]=f[i][j]=temp;//还原
ans=min(ans,c[j]+temp);//记录最小值
}
if(ans==99999999) printf("No solution");
else
printf("%d",ans);
}