Description
Input
接下来的M行里,每行包括3个整数a,b,c.代表a和b之间有一条通路,并且需要花费c元(c <= 100)。
Output
Sample Input
3 3 1 2 1 2 3 1 1 3 1 3 3 1 2 1 1 2 3 2 3 1
Sample Output
3It's impossible.
解法:用floyd求出该无向图的最小环
以知floyd可以求出i到j的最短路,而一个环可以看作是边dis[i][j]+map[i][k]+map[k][j];所以求最小环可以在不断更新最短路中更新最小环。
#include<stdio.h> #include<string.h> #define maxn 1005 #include <algorithm> #include<iostream> #define INF 0xffffff using namespace std; int map[maxn][maxn],vis[maxn],dis[maxn][maxn]; int n,m; void floydcircle() { int ans,minx; ans=INF; for(int i=0;i<maxn;i++) { for(int j=0;j<maxn;j++) { dis[i][j]=map[i][j];//不能先更新最短路再求最小环,因为 } } for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(minx>dis[i][j]+map[i][k]+map[k][j]&&i!=k&&i!=k&&i!=j) { minx=dis[i][j]+map[i][k]+map[k][j];//不能先更新最短路再求最小环,因为i到k和k到j有重合的地方 if(ans>minx) { ans=minx; } } } }
//更新最短路的d[i][j] for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } if(ans>=INF) printf("It's impossible.\n"); else printf("%d\n",ans); } int main(void) { //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { int a,b,c; for(int i=0;i<maxn;i++) { for(int j=0;j<maxn;j++) map[i][j]=INF; } for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); if(map[a][b]>c) { map[a][b]=c; map[b][a]=c; } } floydcircle(); } return 0; }