题意:
给了一个无向图,至多100个点..10000条边..可能有重边..并且每条边有权值..现在请找出一个环..其所有边权值之和最小..
题解:
想继续用BFS搞..发现写不下去了..
那么就用Floyd搞..不过这么写我有个疑问...如:
2 2
1 2 100
2 1 100
答案不应该是200么...但用Floyd的方法做..只能保存这两条边的一条边..结果是No solution...
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #include<cmath> #define oo 1<<29 #define MAXN 105 using namespace std; int Dist[MAXN][MAXN],Graph[MAXN][MAXN],pre[MAXN][MAXN],num,ans[MAXN]; int MC(int nVertex) { int mincircle=oo,i,j,k,x,temp; for (i=1;i<=nVertex;i++) for (j=1;j<=nVertex;j++) Dist[i][j]=Graph[i][j],Dist[i][i]=0;//Dist[i][i]=0,但Graph[i][i]不一定 for(k=1;k<=nVertex;k++) { //新增部分: for(i=1;i<=k;i++) for(j=1;j<i;j++) if (mincircle>Graph[k][i]+Dist[i][j]+Graph[j][k]) //k->i->j->k { mincircle=Graph[k][i]+Dist[i][j]+Graph[j][k]; ans[num=1]=k,x=i; while(x!=-1) { ans[++num]=x; x=pre[x][j]; } } //通常的 floyd 部分: for(i=1;i<=nVertex;i++) for(j=1;j<=nVertex;j++) { temp=Dist[i][k]+Dist[k][j]; if(temp<Dist[i][j]) Dist[i][j]=temp, pre[i][j]=pre[i][k]; } } return mincircle; } int main() { int n,m,u,v,d; scanf("%d%d",&n,&m); memset(pre,-1,sizeof(pre)); for (u=1;u<=n;u++) for (v=1;v<=n;v++) Graph[u][v]=oo; while (m--) { scanf("%d%d%d",&u,&v,&d); if (d<Graph[u][v]) Graph[u][v]=Graph[v][u]=d, pre[u][v]=v,pre[v][u]=u; } if (MC(n)==oo) puts("No solution."); else { for (u=1;u<num;u++) printf("%d ",ans[u]); printf("%d\n",ans[num]); } return 0; }