POJ1679 The Unique MST 生成树+DFS
Posted WDZRMPCBIT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1679 The Unique MST 生成树+DFS相关的知识,希望对你有一定的参考价值。
题意:求一个无向图的最小生成树与次小生成树的边权和是否相等
题解:
首先有一个性质,就是最小生成树上的任意两点的距离就是其在原图中的最短路,严格的证明我不会- -,但是由于Prim Dijkstra算法的过程完全相同,所以这个性质比较显然(不会证就不会证呗为何还要找理由QAQ)
还要一条性质就是无向MST上加入一条边一定会形成一个环,因此我们可以枚举加入一条不在MST上的边e,然后删除MST上形成的环中除e之外的最长的一条边,得到了一个新的最小生成树,由于e一定大于等于删除的那条边,因此得到的新的生成树也一定大于等于MST,因此枚举出的最小的生成树就是次小生成树了。
当然实际操作的时候并不需要每次都找一边最长的边,我们先把MST给存下来,然后DFS出MST上任意两点(i,j)路径上的最长边f[i][j],然后枚举的过程中的新的生成树的长度就是dist_MST+w(u,v)-f[u][v]
#include <queue> #include <vector> #include <functional> #include <cstdio> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN=100+2; const int MAXM=10000+2; struct HASH{ int u,w; HASH *next; HASH(){} HASH(int _u,int _w,HASH *_next):u(_u),w(_w),next(_next){} }*table[MAXN],mem[2*MAXM],*table_MST[MAXN],mem_MST[2*MAXM]; struct NODE{ int u,v,w; NODE(){} NODE(int _u,int _v,int _w):u(_u),v(_v),w(_w){} friend bool operator<(NODE a,NODE b){ return a.w>b.w;} }; int T,N,M,dist,d[MAXN],e[MAXN][MAXN],cnt; bool flag[MAXN],mark[MAXN][MAXN]; priority_queue<NODE> q; void Insert(int u,int v,int w){ table[u]=&(mem[cnt++]=HASH(v,w,table[u]));} void Insert_MST(int u,int v,int w){ table_MST[u]=&(mem_MST[cnt++]=HASH(v,w,table_MST[u]));} int Prim(){ int ret=0; memset(d,0X7F,sizeof(d)); d[1]=0,q.push(NODE(0,1,0)); NODE x; while(!q.empty()){ x=q.top(),q.pop(); if(flag[x.v]) continue; flag[x.v]=1; ret+=x.w; if(x.u) mark[x.u][x.v]=mark[x.v][x.u]=1,Insert_MST(x.u,x.v,x.w),Insert_MST(x.v,x.u,x.w); for(HASH *p=table[x.v];p;p=p->next) if(d[p->u]>p->w) d[p->u]=p->w,q.push(NODE(x.v,p->u,p->w)); } return ret; } void DFS(int u,int w,int f,int b){ for(HASH *p=table_MST[u];p;p=p->next) if(p->u!=f) e[b][p->u]=max(w,p->w),DFS(p->u,max(w,p->w),u,b); } int main(){ cin >> T; while(T--){ cnt=dist=0; memset(e,0,sizeof(e)); memset(mark,0,sizeof(mark)); memset(flag,0,sizeof(flag)); memset(table,0,sizeof(table)); memset(table_MST,0,sizeof(table_MST)); cin >> N >> M; for(int i=1,u,v,w;i<=M;i++){ cin >> u >> v >> w; Insert(u,v,w),Insert(v,u,w); } cnt=0,dist=Prim(); for(int i=1;i<=N;i++) DFS(i,0,0,i); for(int i=1;i<=N;i++) for(HASH *p=table[i];p;p=p->next) if(!mark[i][p->u] && p->w==e[i][p->u]){ flag[0]=1; break; } if(flag[0]) cout << "Not Unique!" << endl; else cout << dist << endl; } return 0; }
以上是关于POJ1679 The Unique MST 生成树+DFS的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1679 The Unique MST (次小生成树)
POJ 1679 The Unique MST(次短生成树)
poj 1679 The Unique MST (判定最小生成树是否唯一)
POJ 1679 The Unique MST 最小生成树/次小生成树