这道题比HDU1599要复杂一点,需要输出最小环的各个点.
详见代码:
/*************************************************************************
> File Name: main.cpp
> Author:Eagles
> Mail:None
> Created Time: 2018年09月08日 星期六 22时48分21秒
> Description:POJ1734,floyd求最小环
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define N 110
int dis[N][N],mp[N][N],pre[N][N];//pre数组用来存dis[i][j]里面j的上一个点
int ans[N];/保存答案的数组
int ans_sum;//答案的点的个数
int n,m;
int be;//最先的环的长度
const int INF=111111;
void init()
{
for (int i=0; i<n; i++)
{
for (int j=0; j<n; j++)
{
dis[i][j]=mp[i][j]=INF;
pre[i][j]=i;
if (i==j)
dis[i][j]=mp[i][j]=0;
}
}
for (int i=0; i<m; i++)
{
int a,b,val;
scanf("%d%d%d",&a,&b,&val);
if (dis[a-1][b-1]>val)
dis[a-1][b-1]=dis[b-1][a-1]=val;
if (mp[a-1][b-1]>val)
mp[a-1][b-1]=mp[b-1][a-1]=val;
}
}
void floyd()
{
be=INF;
for (int i=0; i<n; i++)
{
for (int j=0; j<i; j++)
{
for (int k=j+1; k<i; k++)
{
int tmp=dis[j][k]+mp[j][i]+mp[i][k];
if (tmp<be)//如果此环小于原来的环
{
be=tmp;
ans_sum=0;
int p=pre[j][k];
while (p != j)//回溯
{
ans[ans_sum++]=p;
p=pre[j][p];
}
ans[ans_sum++]=j;
ans[ans_sum++]=i;
ans[ans_sum++]=k;
}
}
}
for (int j=0; j<n; j++)
{
for (int k=0; k<n; k++)
{
int tmp=dis[j][i]+dis[i][k];
if (tmp<dis[j][k])
{
dis[j][k]=tmp;
pre[j][k]=pre[i][k];
}
}
}
}
}
void get_ans()
{
if (be >= INF)
{
printf("No solution.\n");
return ;
}
printf("%d",ans[0]+1);
for (int i=1; i<ans_sum; i++)
{
printf(" %d",ans[i]+1);
}
printf("\n");
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
init();
floyd();
get_ans();
}
return 0;
}