poj1734

链接

给定无向图,点数小于100,边数小于10000,要求最小环。 floyd可以直接做,O(n^3)可以接受。 转移就是d[i][j]+a[i][k]+a[k][j],d数组的含义就是普通的folyd,表示不经过k之后的节点,从ij的最段路径 这样得到的就一定是一个环。

还有要求记录路劲,这是我觉得这题最值得我学习的地方之一。 用递归的方式,记录一个数组mid[i][j],表示如果从编号为k以下的点经过ij可以找到路径,那么最短的路径的一个中间的节点是谁。 用这个数组,可以进行一个递归的方式来寻找中间经过的所有点。这个是可以证明的,如果这条路是ij的最短路,那上面的所有点之间的最短路一定和这条路重合(很好证明,不说了) 这就是临界矩阵记录最短路路径的方法,单次查找是O(n)的,这题的n=100,总体是O(n^4),刚好通过。

额,还有一个挺重要的点,就是memset初始化数组为最大值,会把数组塞满,也就是,如果代码里面有运算是两个或者3个数字相加,没有排除这个最大值参加运算的可能性,那用long long+memset会爆long long。。。就很离谱,所以要注意。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <map>
#include <string.h>
#include <vector>
#define ll long long
using namespace std;
inline int read() {
char c=getchar();int a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
ll n,m,a[101][101],d[101][101];
ll pos[101][101],ans;
vector<ll>path;
const int inf=0x3f3f3f3f;
void get_path(int x,int y)
{
if(pos[x][y]==0)return;
int mid=pos[x][y];
get_path(x,mid);
path.push_back(mid);
get_path(mid,y);
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read(),m=read();
// memset(a,0x3f,sizeof(a));

for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=45574308887988303LL;
// cout<<a[i][j]<<' ';
}
// cout<<endl;
}
// cout<<endl;
for(int i=1;i<=n;i++)a[i][i]=0;
for(int i=1;i<=m;i++)
{
ll x=read(),y=read(),z=read();
a[x][y]=a[y][x]=min(a[x][y],z);
}
memcpy(d,a,sizeof(a));
ans=inf;
for(int k=1;k<=n;k++)
{
for(int i=1;i<k;i++)
{
for(int j=i+1;j<k;j++)
{
if((long long)d[i][j]+a[i][k]+a[k][j]<ans)
{
ans=d[i][j]+a[i][k]+a[k][j];
path.clear();
path.push_back(i);
get_path(i,j);
path.push_back(j);
path.push_back(k);
}
}
}
for(int i=1;i<=n;i++)//Õâ¸öʱºòk¾Í¿ÉÒÔ±»ÆäËû½ÚµãʹÓÃÁË
{
for(int j=1;j<=n;j++)
{
if(d[i][j]>d[i][k]+d[k][j])
{
d[i][j]=d[i][k]+d[k][j];
pos[i][j]=k;
}
}
}
}
if(ans==inf)
{
cout<<"No solution."<<endl;
}
else
{
for(int i=0;i<path.size();i++)
{
cout<<path[i]<<' ';
}
cout<<endl;
}
return 0;
}


posted @ 2024-02-29 14:13  HL_ZZP  阅读(9)  评论(0编辑  收藏  举报