标签:namespace math memset inf oid 访问 prim ios bsp
//判断唯一MST的思想 //先用Prim算法求出最小生成树的值 //枚举MST体系外的每一条边,加入MST,必然形成一个环,判断u - v的 //权值边是否和u - v路径的最大权值边相等,如果相等,则存在不止一条MST #include<iostream>//Judge 是否为唯一MST #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define inf (0x3f3f3f3f) using namespace std; const int maxn = 100 + 15; int Grape[maxn][maxn];//u - v节点之间权值 int n,m;//节点数 边数 bool vis[maxn]; int p[maxn],d[maxn]; int maxLen[maxn][maxn];//u - v路径最长距离 int stack[maxn];//储存MST节点 void Prim() { memset(vis,false,sizeof(vis)); memset(p,-1,sizeof(p)); memset(d,inf,sizeof(d)); int top = 0; d[1] = 0; while(true) { int mincost = inf,u = 0; for(int i=1;i<=n;++i) { if(!vis[i]&&d[i]<mincost)//节点未被访问 { mincost = d[i]; u = i; } }//选取最小节点 //更新和MST节点的maxLen vis[u] = true; if(mincost==inf) break; for(int v=0;v!=top;++v)// u 与 stack中 { if(p[u]!=-1) maxLen[stack[v]][u] = maxLen[u][stack[v]] = max(maxLen[stack[v]][p[u]],mincost); }//更新maxLen stack[top++] = u;//MST中加入节点 //u -> 更新 v for(int v=1;v<=n;++v) { if(!vis[v]&&Grape[u][v]!=-1&&d[v]>Grape[u][v]) { d[v] = Grape[u][v]; p[v] = u; } } } int minn = inf; for(int u=1;u<=n;++u) { for(int v=1;v<=n;++v) { if(u!=v&&p[u]!=v&&p[v]!=u)//u v为体系外的边 minn = min(minn,abs(Grape[u][v]-maxLen[u][v])); } } //cout<<minn<<endl; if(minn==0) cout<<"Not Unique!"<<endl; else{ int sum = 0; for(int v=1;v<=n;++v) if(p[v]!=-1) sum += Grape[v][p[v]]; cout<<sum<<endl; } } int main() { int t; cin>>t; while(t--) { memset(Grape,-1,sizeof(Grape)); memset(maxLen,0,sizeof(maxLen)); cin>>n>>m; int u,v,w; for(int i=0;i!=m;++i) { cin>>u>>v>>w; Grape[u][v] = Grape[v][u] = w;//如果u-v之间权值为-1则不存在边 }//构图 Prim(); } }
标签:namespace math memset inf oid 访问 prim ios bsp
原文地址:https://www.cnblogs.com/newstartCY/p/11559432.html