POJ1734.Cleaning Shifts

利用Floyd的性质:即循环到k时,d[i][j] (I<k,j<k)在比k小的点内已到达最短距离 在枚举k的同时 k也是我们分切环的点,

d[i][j]+a[i][k]+a[k][j]

因为d[I][j]必然不经过k,所以a[I][k]+a[k][j]必然是另外一条到达j的路径,同时我们也保证了d[i][j]为I->j的最短距离

我们也可以这样理解:枚举到最优路径的最大点k的时候,必然会有d[I][j]+a[i][k]+a[k][j]

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f

int n,m,ans=INF;
int a[110][110],d[110][110],f[110][110];
vector<int>vec;

void get(int x,int y){
    if(f[x][y]==0) return ;
    get(x,f[x][y]);
    vec.push_back(f[x][y]);
    get(f[x][y],y);
}

int main()
{
    cin>>n>>m;
    memset(a,0x3f,sizeof a);
    for(int i=1;i<=n;i++) a[i][i]=0;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        a[y][x]=a[x][y]=min(a[x][y],z);
    }
    memcpy(d,a,sizeof a);
    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[j][k]+a[k][i]<ans){
                    ans=d[i][j]+a[j][k]+a[k][i];
                    vec.clear();
                    vec.push_back(i);
                    get(i,j);
                    vec.push_back(j);
                    vec.push_back(k);
                }
        for(int i=1;i<=n;i++)
            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];
                    f[i][j]=k;
                }
    }
    if(ans==INF){
        puts("No solution.");
        return 0;
    }
    for(int i=0;i<vec.size();i++)
        cout<<vec[i]<<' ';
    cout<<endl;
    return 0;
}
发布了38 篇原创文章 · 获赞 5 · 访问量 840

猜你喜欢

转载自blog.csdn.net/Fooooooo/article/details/104751954