URAL 1004: Sightseeing Trip

题目链接:http://acm.timus.ru/problem.aspx?num=1004


题目大意:

求无向图最小环,若有解需输出方案


算法:

floyd的基础应用,

注意排除两点环


代码如下:

#include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
using namespace std;

int d[150][150],edge[150][150],nxt[150][150];
int stk[150],top;
const int INF=10000000;

int main()
{
  int n,m;
  while(scanf("%d",&n),n!=-1)
    {
    	scanf("%d",&m);
    	for(int i=0;i<n;i++)
    	for(int j=0;j<n;j++)
    	{
    		d[i][j]=edge[i][j]=INF;
    		nxt[i][j]=j;
    	}
      int ans=INF;
      while(m--)
        {
          int u,v,w;
          scanf("%d%d%d",&u,&v,&w);
          u--;
          v--;
          if(w<d[u][v])
          {
          edge[u][v]=edge[v][u]=d[u][v]=d[v][u]=w;
          }
        }
        for(int k=0;k<n;k++)
        {
					for(int i=0;i<k;i++)
        	for(int j=i+1;j<k;j++)
        	{
        		if(ans>d[i][j]+edge[j][k]+edge[k][i])
        		{
        			top=0;
        			ans=d[i][j]+edge[j][k]+edge[k][i];
        			for(int tmp=i;tmp!=j;tmp=nxt[tmp][j])
        			{
        			stk[top++]=tmp;
        			}
        			stk[top++]=j;
        			stk[top++]=k;
        		}
        	}
        	for(int i=0;i<n;i++)
        	for(int j=0;j<n;j++)
        	{
        		if(d[i][j]>d[j][k]+d[k][i])
        		{
        			d[i][j]=d[j][k]+d[k][i];
        			nxt[i][j]=nxt[i][k];
        		}
        	}
        }
      if(ans==INF)
        {
          puts("No solution.");
        }
      else
        {
          for(int i=0;i<top;i++)
          {
          	if(i)putchar(' ');
          	printf("%d",stk[i]+1);
          }
          puts("");
        }
    }
  return 0;
}

你可能感兴趣的:(URAL 1004: Sightseeing Trip)