【题目链接】

点击打开链接

【算法】

先求出图的最小生成树

枚举不在最小生成树上的边,若加入这条边,则形成了一个环,如果在环上且在最小生成树上的权值最大的边等于

这条边的权值,那么,显然最小生成树不唯一

树上倍增可以解决这个问题

【代码】

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXN 110
#define MAXM 1000010
#define MAXLOG 20 struct Edge
{
int x,y;
long long w;
} edge[MAXM]; int T,n,m,i;
long long val;
vector< pair<int,long long> > e[MAXN];
bool on_mst[MAXM];
int fa[MAXN],anc[MAXN][MAXLOG],dep[MAXN];
long long mx[MAXN][MAXLOG];
bool not_unique; inline bool cmp(Edge a,Edge b) { return a.w < b.w; }
inline int get_root(int x)
{
if (fa[x] == x) return x;
return fa[x] = get_root(fa[x]);
}
inline void kruskal()
{
int i,x,y,sx,sy;
long long w;
for (i = ; i <= n; i++) fa[i] = i;
for (i = ; i <= m; i++) on_mst[i] = false;
sort(edge+,edge+m+,cmp);
for (i = ; i <= m; i++)
{
x = edge[i].x;
y = edge[i].y;
w = edge[i].w;
sx = get_root(x);
sy = get_root(y);
if (sx != sy)
{
on_mst[i] = true;
val += w;
fa[sx] = sy;
e[x].push_back(make_pair(y,w));
e[y].push_back(make_pair(x,w));
}
}
}
inline void build(int u)
{
int i,v;
for (i = ; i < MAXLOG; i++)
{
anc[u][i] = anc[anc[u][i-]][i-];
mx[u][i] = max(mx[u][i-],mx[anc[u][i-]][i-]);
}
for (i = ; i < e[u].size(); i++)
{
v = e[u][i].first;
if (anc[u][] != v)
{
dep[v] = dep[u] + ;
anc[v][] = u;
mx[v][] = e[u][i].second;
build(v);
}
}
}
inline long long get(int x,int y)
{
int i,t;
long long ans = ;
if (dep[x] > dep[y]) swap(x,y);
t = dep[y] - dep[x];
for (i = ; i < MAXLOG; i++)
{
if (t & ( << i))
{
ans = max(ans,mx[y][i]);
y = anc[y][i];
}
}
if (x == y) return ans;
for (i = MAXLOG - ; i >= ; i--)
{
if (anc[x][i] != anc[y][i])
{
ans = max(ans,max(mx[x][i],mx[y][i]));
x = anc[x][i];
y = anc[y][i];
}
}
return max(ans,max(mx[x][],mx[y][]));
}
int main()
{ scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
val = ;
not_unique = false;
for (i = ; i <= n; i++)
{
dep[i] = ;
e[i].clear();
memset(anc[i],,sizeof(anc[i]));
memset(mx[i],,sizeof(mx[i]));
}
for (i = ; i <= m; i++) scanf("%d%d%lld",&edge[i].x,&edge[i].y,&edge[i].w);
kruskal();
build();
for (i = ; i <= m; i++)
{
if (!on_mst[i])
not_unique |= (get(edge[i].x,edge[i].y) == edge[i].w);
}
if (not_unique) printf("Not Unique!\n");
else printf("%lld\n",val);
} return ; }

【POJ 1679】 The Unique MST的更多相关文章

  1. 【POJ 1679】The Unique MST(次小生成树)

    找出最小生成树,同时用Max[i][j]记录i到j的唯一路径上最大边权.然后用不在最小生成树里的边i-j来替换,看看是否差值为0. #include <algorithm> #includ ...

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

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19941   Accepted: 6999 D ...

  3. bzoj 2295: 【POJ Challenge】我爱你啊

    2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec  Memory Limit: 128 MB Description ftiasch是个十分受女生欢迎的同学,所以 ...

  4. 【链表】BZOJ 2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 382  Solved: 111[Submit][S ...

  5. BZOJ2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 284  Solved: 82[Submit][St ...

  6. BZOJ2293: 【POJ Challenge】吉他英雄

    2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 80  Solved: 59[Submit][Stat ...

  7. BZOJ2287: 【POJ Challenge】消失之物

    2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 254  Solved: 140[Submit][S ...

  8. BZOJ2295: 【POJ Challenge】我爱你啊

    2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 126  Solved: 90[Submit][Sta ...

  9. BZOJ2296: 【POJ Challenge】随机种子

    2296: [POJ Challenge]随机种子 Time Limit: 1 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 114  Solv ...

随机推荐

  1. 安装lnmp

    一.yum安装php 1.更新更新yum源:rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rp ...

  2. 【转】C语言中access函数

    头文件:unistd.h 功 能: 确定文件或文件夹的访问权限.即,检查某个文件的存取方式,比如说是只读方式.只写方式等.如果指定的存取方式有效,则函数返回0,否则函数返回-1. 用 法: int a ...

  3. MySQL-----查

    数据库在我眼中就是增删改查,而查,我觉得是数据库最费劲的,数据库的花式查,各种查.下面咱们不废话,就是干. 查: **查数据库版本** select version(); **查登录用户** sele ...

  4. git-svn操作

    1.git svn clone --username=chenzheng   http://10.0.0.178/repos/trunk/hxqcgf/auto_accessories.admin.h ...

  5. 【转】Java IO流 overview

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  6. windows开启远程

    windows开启远程桌面超级简单,跟linux相比太简单了. 补充:有瑕疵,应该是远程中的远程桌面属性打钩,但是W8.1没有这个选项,W7可以,其次创建一个管理员账户,身份是管理员,不是标准用户,要 ...

  7. Delphi:ClientDataset+TDataSetProvider的数据保存问题

    看到一篇介绍ClientDataSet和TDataSetProvider,非常精彩,特此保存. ==================================================== ...

  8. 04-js的运算符

    <html> <head> <title>js的运算符学习</title> <meta charset="UTF-8"/> ...

  9. lambda简单记录

    lambda表达式对集合的一些操作,持续记录一下新的用法 List<Integer> list = new ArrayList<>(); list.add(1); list.a ...

  10. 洛谷 P1883 函数

    P1883 函数 题目描述 给定n个二次函数f1(x),f2(x),...,fn(x)(均形如ax^2+bx+c),设F(x)=max{f1(x),f2(x),...,fn(x)},求F(x)在区间[ ...