1. 程式人生 > >2018.09.15 poj1734Sightseeing trip(floyd求最小環)

2018.09.15 poj1734Sightseeing trip(floyd求最小環)

hdu1599差不多.。 只是需要輸出方案。 這個可以遞迴求解。 程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#define inf 50005
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3
)+(ans<<1)+(ch^48),ch=getchar(); return ans; } int dis[105][105],f[105][105],ans; int n,m,pred[105][105][105],ansi,ansj,ansk; inline void solve(int k,int u,int v){ if(!k){printf("%d",v);return;} if(pred[k][u][v]==-1){solve(k-1,u,v);return;} solve(k-1,u,k),putchar(' '),solve(k-1,k,v); } inline
int min(int a,int b){return a<b?a:b;} int main(){ memset(pred,-1,sizeof(pred)),n=read(),m=read(); for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)dis[i][j]=f[i][j]=inf; for(int i=1;i<=n;++i)dis[i][i]=f[i][i]=0; for(int i=1;i<=m;++i){ int u=read(),v=read(),w=read(); dis[u][v]=dis[v][u]=f[u][v]=f[v][u]=min(f[u][v],w); } ans=inf; for
(int k=1;k<=n;++k){ for(int i=1;i<k;++i)for(int j=1;j<k;++j){ if(i==j)continue; if(dis[i][j]+f[i][k]+f[k][j]<ans) ans=dis[i][j]+f[i][k]+f[k][j],ansi=i,ansj=j,ansk=k; } for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) if(dis[i][j]>dis[i][k]+dis[k][j]){ dis[i][j]=dis[i][k]+dis[k][j],pred[k][i][j]=k; } } if(ans==inf)puts("No solution."); else printf("%d %d ",ansk,ansi),solve(ansk-1,ansi,ansj); return 0; }