POJ 1734

题意:给定一个无向图,有重边,求最小代价环,环上点数必须大于2

题解:类似floyd,在进行最小距离的同时,枚举点k的两端是否形成回路,如果形成,必定是没有经过重复点的,因为那样就不是最小距离,而经过点k的弧的松弛操作还没进行,所以也不会经过k

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 using namespace std;

 5 const int inf=1<<29;

 6 int dist[105][105],map[105][105],pre[105][105];

 7 int main()

 8 {

 9     int n,m;

10     while(scanf("%d%d",&n,&m)!=EOF)

11     {

12         memset(map,-1,sizeof(map));

13         memset(pre,-1,sizeof(pre));

14         memset(dist,-1,sizeof(dist));

15         for(int i=0; i<m; i++)

16         {

17             int a,b,c;

18             scanf("%d%d%d",&a,&b,&c);

19             if(dist[a][b]==-1)

20                 dist[a][b]=dist[b][a]=map[a][b]=map[b][a]=c;

21             else

22                 dist[a][b]=dist[b][a]=map[a][b]=map[b][a]=min(map[a][b],c);

23             pre[a][b]=a;

24             pre[b][a]=b;

25         }

26         for(int i=1;i<=n;i++)

27             dist[i][i]=map[i][i]=0;

28         int ans=inf,path[105],top;

29         for(int k=1; k<=n; k++)

30         {

31             for(int i=1; i<k; i++)

32                 for(int j=i+1; j<k; j++)

33                 {

34                     if(dist[i][j]!=-1&&map[i][k]!=-1&&map[k][j]!=-1&&ans>dist[i][j]+map[i][k]+map[k][j])

35                     {

36                         ans=dist[i][j]+map[i][k]+map[k][j];

37                         int t=j;

38                         top=0;

39                         while(t!=i)

40                         {

41                             path[top++]=t;

42                             t=pre[i][t];

43                         }

44                         path[top++]=i;

45                         path[top++]=k;

46                     }

47                 }

48             for(int i=1; i<=n; i++)

49                 for(int j=1; j<=n; j++)

50                     if(dist[i][k]!=-1&&dist[k][j]!=-1&&(dist[i][j]==-1||dist[i][j]>dist[i][k]+dist[k][j]))

51                     {

52                         dist[i][j]=dist[i][k]+dist[k][j];

53                         pre[i][j]=pre[k][j];

54                     }

55         }

56         if(ans==inf)

57         {

58             printf("No solution.\n");

59             continue;

60         }

61         for(int i=0; i<top-1; i++)

62             printf("%d ",path[i]);

63         printf("%d\n",path[top-1]);

64     }

65     return 0;

66 }

你可能感兴趣的:(poj)