POJ 1679 The Unique MST

来源:互联网 发布:oracl创建数据库 编辑:程序博客网 时间:2024/04/24 19:37

大意不再赘述。

思路:让你求次小生成树,我们可以枚举每一条边,之后删除在MST中的最大的一条边,然后保存最小值,这就是权值第二大的树,即次小生成树。

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;const int MAXN = 110;const int INF = 0x3f3f3f3f;int w[MAXN][MAXN];int path[MAXN][MAXN];bool use[MAXN][MAXN];int fa[MAXN];int d[MAXN];int n, m;int cnt1, cnt2;void init(){cnt1 = cnt2 = 0;memset(w, INF, sizeof(w));memset(use, 0, sizeof(use));}void Prim(int src){bool vis[MAXN] = {0};for(int i = 1; i <= n; i++) d[i] = (i == src)? 0:INF;for(int i = 1; i <= n; i++) fa[i] = -1;for(int i = 1; i <= n; i++){int x, m = INF;for(int y = 1; y <= n; y++) if(!vis[y] && m > d[y]) m = d[x=y];for(int y = 1; y <= n; y++) if(vis[y]) //扫描已经在MST中的边 {path[x][y] = path[y][x] = max(path[fa[x]][y], w[fa[x]][x]);//path[x][y] = path[y][x] = max(path[fa[x]][y], d[x]);}vis[x] = 1;use[fa[x]][x] = use[x][fa[x]] = 1; //标记在MST中 cnt1 += m;for(int y = 1; y <= n; y++) if(d[y] > w[x][y]){d[y] = w[x][y];fa[y] = x;}}}void SMST(){for(int i = 1; i < n; i++){for(int j = i+1; j <= n; j++) if(!use[i][j] && w[i][j] != INF){cnt2 = cnt1 + w[i][j]-path[i][j]; //枚举每一条边 if(cnt1 == cnt2){printf("Not Unique!\n");return ;}}}printf("%d\n", cnt1);}void read_case(){init();scanf("%d%d", &n, &m);while(m--){int u, v, cost;scanf("%d%d%d", &u, &v, &cost);w[u][v] = w[v][u] = cost;}}void solve(){read_case();Prim(1);SMST();}int main(){int T;scanf("%d", &T);while(T--){solve();}return 0;}


原创粉丝点击