The Unique MST(poj 1679)

题意:求次小生成树,若权值和与最小生成树相等,输出"Not Unique!" ;否则,输出mst

/*
  次小生成树
  首先明白一点,次小生成树是由最小生成树改变一条边得来的,然后我们就可以先求出最小生成树,
  然后枚举没在最小生成树中的边(x、y、z),用这条边来替换树中x、y之间的一条边,很显然,替换
  时应该替换x、y中的最长边,所以可以预处理出树中x、y之间的最长边。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 110
#define INF 1000000000
using namespace std;
int head[N],g[N][N],fa[N],vis[N*N],n,m,cnt,mst;
struct node
{
    int x,y,z;
};node ee[N*N];
struct Node
{
    int v,pre,t;
};Node e[N*2];
bool cmp(const node&s1,const node&s2)
{
    return s1.z<s2.z;
}
int find(int x)
{
    if(fa[x]==x)return x;
    return fa[x]=find(fa[x]);
}
void add(int x,int y,int z)
{
    ++cnt;
    e[cnt].v=y;
    e[cnt].t=z;
    e[cnt].pre=head[x];
    head[x]=cnt;
}
void dfs(int s,int now,int from,int mmx)
{
    g[s][now]=mmx;
    for(int i=head[now];i;i=e[i].pre)
      if(e[i].v!=from)
          dfs(s,e[i].v,now,max(mmx,e[i].t));
}
void work()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&ee[i].x,&ee[i].y,&ee[i].z);
    }
    sort(ee+1,ee+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        int a=find(ee[i].x),b=find(ee[i].y);
        if(a!=b)
        {
            fa[a]=b;mst+=ee[i].z;vis[i]=1;
            add(ee[i].x,ee[i].y,ee[i].z);
            add(ee[i].y,ee[i].x,ee[i].z);
        }
    }
    for(int i=1;i<=n;i++)
      dfs(i,i,-1,0);
    int ans=INF;
    for(int i=1;i<=m;i++)
      if(!vis[i])
          ans=min(ans,mst-ee[i].z+g[ee[i].x][ee[i].y]);
    if(ans==mst)printf("Not Unique!\n");
    else printf("%d\n",mst);
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        memset(g,0,sizeof(g));
        memset(fa,0,sizeof(fa));
        memset(head,0,sizeof(head));
        memset(vis,0,sizeof(vis));
        mst=cnt=0;
        work();
    }
    return 0;
}
时间: 2024-12-29 12:57:15

The Unique MST(poj 1679)的相关文章

hdu 1679 The Unique MST (克鲁斯卡尔)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24152   Accepted: 8587 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

PKU 1679 The Unique MST(解题报告)

思路是先找出最小生成树,并记录每条遍,要想说明是唯一的最小生成树,那么他的每条边都是必不可少的,然后我们可以枚举所有最小生成树的边 ,依次去掉,看是否还能不能组成一棵相同权值和的mst.就是因为当初的一点点儿错误导致 ,一周了将近,才拿出来,一眼看出bug! #include<iostream> #include<string.h> #include<queue> #include<algorithm> using namespace std; const

POJ - 1679 The Unique MST (次小生成树)

Description Given a connected undirected graph, tell if its minimum spanning tree is unique. 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 followin

POJ 1679:The Unique MST(次小生成树&amp;&amp;Kruskal)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19941   Accepted: 6999 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

poj 1679 The Unique MST (判断最小生成树是否唯一)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20679   Accepted: 7255 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

POJ 1679 The Unique MST(求最小生成树是否唯一)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20430   Accepted: 7186 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

poj 1679 The Unique MST (次小生成树)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20293   Accepted: 7124 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

HDU 1325 Is It A Tree? (POJ 1308)

并查集问题... 这题以前做过-- 以前做过-- 做过-- 过-- 不过重做时候被吭得异常之爽-- 在判断 vis[i]的时候.我记得标准C++是非0 即为真. 而我用C++ 提交的时候 if(vis[i]) 去直接给我WA了. 用G++ 就AC了...然后改成if(vis[i]==1) 交C++ 就AC了. 特瞄的我每次初始化都把 vis[i] 都赋值为 0 了..都能出这种错? 求路过大神明示我的错误. 题意是判断是否是一棵树. 不能存在森林,用并查集合并,每个点的入度不能超过1. 比如 1

HDU 1535 Invitation Cards (POJ 1511)

两次SPFA.求 来 和 回 的最短路之和. 用Dijkstra+邻接矩阵确实好写+方便交换,但是这个有1000000个点,矩阵开不了. d1[]为 1~N 的最短路. 将所有边的 邻点 交换. d2[] 为 1~N 的最短路. 所有相加为 所要答案. 忧伤的是用SPFA  "HDU 1535"  AC了,但是POJ 一样的题 "POJ 1511" 就WA了. 然后强迫症犯了,不停的去测试. 题意中找到一句关键话 :Prices are positive integ