【POJ 1679】 The Unique MST
【题目链接】
【算法】
先求出图的最小生成树
枚举不在最小生成树上的边,若加入这条边,则形成了一个环,如果在环上且在最小生成树上的权值最大的边等于
这条边的权值,那么,显然最小生成树不唯一
树上倍增可以解决这个问题
【代码】
- #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的更多相关文章
- 【POJ 1679】The Unique MST(次小生成树)
找出最小生成树,同时用Max[i][j]记录i到j的唯一路径上最大边权.然后用不在最小生成树里的边i-j来替换,看看是否差值为0. #include <algorithm> #includ ...
- POJ 1679:The Unique MST(次小生成树&&Kruskal)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19941 Accepted: 6999 D ...
- bzoj 2295: 【POJ Challenge】我爱你啊
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MB Description ftiasch是个十分受女生欢迎的同学,所以 ...
- 【链表】BZOJ 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 382 Solved: 111[Submit][S ...
- BZOJ2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 284 Solved: 82[Submit][St ...
- BZOJ2293: 【POJ Challenge】吉他英雄
2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 80 Solved: 59[Submit][Stat ...
- BZOJ2287: 【POJ Challenge】消失之物
2287: [POJ Challenge]消失之物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 254 Solved: 140[Submit][S ...
- BZOJ2295: 【POJ Challenge】我爱你啊
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 126 Solved: 90[Submit][Sta ...
- BZOJ2296: 【POJ Challenge】随机种子
2296: [POJ Challenge]随机种子 Time Limit: 1 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 114 Solv ...
随机推荐
- 分布式集群算法 memcached 如何实现分布式?
memcached 是一个”分布式缓存”,然后 memcached 并不像 mongoDB 那 样,允许配置多个节点,且节点之间”自动分配数据”. 就是说--memcached 节点之间,是不互相通信 ...
- 洛谷 3106 [USACO14OPEN]GPS的决斗Dueling GPS's 3720 [AHOI2017初中组]guide
[题解] 这两道题是完全一样的. 思路其实很简单,对于两种边权分别建反向图跑dijkstra. 如果某条边在某一种边权的图中不是最短路上的边,就把它的cnt加上1.(这样每条边的cnt是0或1或2,代 ...
- Windows 下安装 Node.js
搭建博客系列的 Node.js 环境安装.Windows 下面安装可以通过图形化界面进行安装,非常方面. 1.打开 Node.js 官网,下载对应版本的安装包(msi 后缀的) 2.双击运行下载的程序 ...
- Leetcode 208.实现前缀树
实现前缀树 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie(); trie.insert ...
- 添物不花钱学JavaEE(基础篇)-XML
XML(Extensible Markup Language) XML在日常工作中经常用到,必须有个了解,不过认识一下即可,不要太浪费时间.实际用到 参考图书 <XML入门经典>大而全,不 ...
- 7-19 求链式线性表的倒数第K项(20 分)(单链表定义与尾插法)
给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理). 输出格式 ...
- android listVIew实现button按钮监听程序
1.重写simpleAdapter 方法@Override public HashMap<String,String> getItem(int position) { // TODO Au ...
- ****Call to a member function item() on a non-object
A PHP Error was encountered Severity: Error Message: Call to a member function item() on a non-objec ...
- codeforces 762E(cdq分治)
题意: n个电台,每个电台有三个属性xi, ri, fi.分别代表电台的坐标,电台的播报范围,以及播报的频率. 对于一对电台i, j,若min(ri, rj) >= |xi - xj|,那么他们 ...
- Mycat集群方案收集(待实践)
先收集,后续再实践. 我想,市面上开源方案中,涉及到高可用和负载均衡的部署,无论是哪一个产品应用,都基本离不开LVS+Keepalived+HAProxy+Nginx等等. 下面是收集的教程: htt ...