The Unique MST
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 22668 | Accepted: 8038 |
Description
Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
【次小生成树】:
重要的是理解求次小生成树的过程。求次小生成树建立在Prim算法的基础上。可以确定的是,次小生成树肯定是由最小生成树删去一条边再加上一条边得到。那么我们应该删去哪条边再加上哪条边呢?假设两点u,v之间有一条边且这条边不在MST中,那么可以尝试加上这条边。但是加上这条边以后会出现环,则一定要去掉回路上的一条边,这条边应该选择回路上权值最大的那条边(毕竟权值要求尽量小)。尝试对每对点对进行上述操作,那么最小的那个结果就是次小生成树。
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> #define debug() puts("++++") #define gcd(a,b) __gcd(a,b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a,b,sizeof(a)) #define sz size() #define be begin() #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define rep(i,x,n) for(int i=(x); i<=(n); i++) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> P; const int INF = 0x3f3f3f3f; const LL LNF = 1e18; const int maxm = 1e6 + 10; const double PI = acos(-1.0); const double eps = 1e-8; const int dx[] = {-1,1,0,0,1,1,-1,-1}; const int dy[] = {0,0,1,-1,1,-1,1,-1}; int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}}; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int mod = 10056; #define inf 0x3f3f3f3f #define ll long long const int maxn = 10010; int u,v,w; int n,m,ans,k,sum,cnt; struct node { int u,v,w; }e[maxn]; int fa[maxn]; int mst[maxn]; int Find(int x) { if(fa[x]!=x) fa[x]=Find(fa[x]); return fa[x]; } void join(int x,int y) { int xx = Find(x); int yy = Find(y); fa[xx]=yy; } bool cmp(node a,node b) { return a.w<b.w; } void kruskal() { rep(i,1,n-1) //枚举mst内的n-1个点 { cnt=0,sum=0; rep(j,1,n) fa[j]=j; //每次枚举待删边 重新设置 rep(j,1,m) { if(j != mst[i]) //枚举不在mst中的每一条边 if(Find(e[j].u) != Find(e[j].v)) { join(Find(e[j].u), Find(e[j].v)); sum += e[j].w; cnt++; } } if(cnt==n-1 && sum==ans) //最小=次小——>不唯一 { printf("Not Unique!\n"); return ; } } printf("%d\n",ans); } int main() { int t; scanf("%d",&t); while(t--) { sum=0,k=0,ans=0; scanf("%d %d",&n, &m); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1; i<=m; i++) scanf("%d %d %d",&e[i].u, &e[i].v, &e[i].w); sort(e+1,e+m+1,cmp); for(int i=1;i<=m;i++) //kruskal造mst数组存储其中包含的边的编号 { int x=Find(e[i].u); int y=Find(e[i].v); if(x != y) { join(x,y); ans+=e[i].w; mst[++k]=i; //先生成mst,存储mst的每一条边 } } kruskal(); //然后枚举删除每一条mst中的边,看是否能找出一课次小生成树的权值和最小生成树的权值相等。 //如果相等,则不唯一 } } /* 【题意】 给你n个点m条边的图,判断图的最小生成树是否唯一。 【类型】 次小生成树 【分析】 首先求出最小生成树的结果sum,并记录每条边是否属于最小生成树,如果存在和sum相同的生成树,则此生成树一定包含不属于最小生成树的边,
即枚举每条不属于最小生成树的边,对每条边求最小生成树,如果结果和sum相同,则not unique,否则最小生成树唯一,输出sum. 【时间复杂度&&优化】 16ms 【trick】 */
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 22668 | Accepted: 8038 |
Description
Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!