poj1734(求最小环)

4923: Poj1734 Sightseeing trip

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 15  Solved: 6
[Submit][Status][Web Board]

Description

给定一张无向图,求图中一个至少包含3个点的环,环上的节点不重复,并且环上的边的长度之和最小。该问题称
为无向图的最小环问题。在本题中,你需要输出最小环的方案,若最小环不唯一,输出任意一个均可。若无解,输
出"No solution."。图的节点数不超过100。

Input

Output

Sample Input

5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20

Sample Output

1 3 5 2
d[i][j]在外层循环刚开始时表示1...k-1的最短路距离那么d[i][j]+a[i][k]+a[k][j]构成一个环,更新最小环即可
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;

const int maxn=300+10;
const int nil=0x3f3f3f3f;

int a[maxn][maxn],pos[maxn][maxn],d[maxn][maxn];
vector<int>path;
stack<int>s;

void getpath(int x,int y){
     if(pos[x][y]==-1) return ;
     getpath(x,pos[x][y]);
     path.push_back(pos[x][y]);
     getpath(pos[x][y],y);
}

int main(){
    int n,m,x,y,w;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++){
        for (int j=1;j<=n;j++){
            a[i][j]=d[i][j]=nil;
            pos[i][j]=-1;
        }
    }
    for (int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&w);
        d[x][y]=d[y][x]=a[x][y]=a[y][x]=min(a[x][y],w);
    }
    int ans=nil;
    for (int k=1;k<=n;k++){
        for (int i=1;i<k;i++)
            for (int j=i+1;j<k;j++)
                if(ans>(long long)d[i][j]+a[i][k]+a[k][j]){
                    ans=d[i][j]+a[i][k]+a[k][j];
                    path.clear();
                    path.push_back(i);
                    getpath(i,j);
                    path.push_back(j);
                    path.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];
                    pos[i][j]=k;
                }
            }
        }
    }
    if(ans==nil) printf("No solution.");
    else {
        printf("%d",path[0]);
        for (int i=1;i<path.size();i++) printf(" %d",path[i]);
    }
return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/lmjer/p/9349098.html