CF160D
题意:给你一个图,判断每条边是否在最小生成树MST上,不在输出none,如果在所有MST上就输出any,在某些MST上输出at least one;
分析:首先必须知道在最小生成树上的边的权值一定是等于任意最小生成树上的某条边的权值;那么我们按边的权值排序,每次同时加入权值相等的边
如果加入这条边之后形成loop那么这条边肯定不是最小生成树上的边,因为在此次加边之前,图上边的权值肯定是小于此次加入的边的权值的,如果加入这条边之后形成环,那么肯定不是MST上的边;加完边之后,如果这条边是bridge,那么这条边肯定是any,因为这条边是连接两个连通块的最小唯一边,如果边在剩下的边肯定在某些MST上;
注意:每一个阶段加完边之后要,要求出此阶段的联通情况,然后一个联通快缩点,然后在继续,这样每条边最多被经历一次,时间是O(m);
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<stack>
using namespace std;
const int N = +;
struct node{
int v,id;
node(){}
node(int v,int id):v(v),id(id){}
};
vector<node> G[N];
int pre[N], low[N], eccno[N], dfs_clock, ecc_cnt;
stack<int> SK;
int an[N];
int num;
int vis[N];
void dfs(int u,int fa) {
pre[u] = low[u] = ++dfs_clock;
int sz = G[u].size();
bool first = true;
for (int i = ;i < sz; i++) {
int v = G[u][i].v;
if (v == fa && first) {
first = false;
continue;
}
if (pre[v] == ) {
dfs(v,u);
low[u] = min(low[u], low[v]);
if (low[v] > pre[u]) an[G[u][i].id] = ;
}else {
low[u] = min(low[u],pre[v]);
}
} } int n,m;
struct edge{
int u,v,w,id;
edge(){}
edge(int u,int v,int w, int id):u(u),v(v),w(w),id(id){}
bool operator < (const edge &p) const{
return w < p.w;
}
};
vector<edge> Eg;
int p[N];
int find(int x) {
return p[x] == x ? x : p[x] = find(p[x]);
}
int mark[N];
void build_graph(){
sort(Eg.begin(),Eg.end());
for (int i = ; i <= n; i++) p[i] = i;
memset(mark,,sizeof(mark));
for (int i = ; i < Eg.size(); i++) {
int j = i;
for (; j < Eg.size() && Eg[j].w == Eg[j+].w; j++);
for (int k = i; k <= j; k++) {
int u = Eg[k].u, v = Eg[k].v, w = Eg[k].w;
int x = find(u), y = find(v);
if (x != y) {
G[x].push_back(node(y,Eg[k].id));
G[y].push_back(node(x,Eg[k].id));
an[Eg[k].id] = ;
pre[x] = pre[y] = ;
mark[k] = x;
}
}
dfs_clock = ;
for (int k = i; k <= j; k++) {
if (mark[k] && pre[mark[k]] == ) dfs(mark[k],-);
}
for (int k = i; k <= j; k++) {
int u = Eg[k].u, v = Eg[k].v, w = Eg[k].w;
int x = find(u), y = find(v);
if (x != y) {
p[x] = y;
G[x].clear(); G[y].clear();
}
}
i = j;
} }
void solve(){
memset(an,,sizeof(an));
build_graph();
for (int i = ; i < m; i++) {
if (an[i] == ) printf("none\n");
else if (an[i] == ) printf("at least one\n");
else if (an[i] == ) printf("any\n");
}
}
int main(){
while (~scanf("%d%d",&n,&m)) {
Eg.clear();
for (int i = ; i < m; i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Eg.push_back(edge(u,v,w,i));
}
solve();
} return ;
}
CF160D的更多相关文章
- [CF160D]Edges in MST
[CF160D]Edges in MST 题目大意: 一个\(n(n\le10^5)\)个点,\(m(m\le10^5)\)条边的连通图.对于图中的每条边,判断它与该图最小生成树的关系: 在该图所有的 ...
- [CF160D]Edges in MST (最小生成树+LCA+差分)
待填坑 Code //CF160D Edges in MST //Apr,4th,2018 //树上差分+LCA+MST #include<cstdio> #include<iost ...
随机推荐
- 创建xml时,设置xml编码问题
OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("GBK"); XMLW ...
- Unable to locate package update
碰到这个问题后找到这个帖子就转了过来 当用apt-get更新软件包时常出现错误提示Unable to locate package update, 尤其是在ubuntu server上,解决方法是: ...
- Debian 如何更改hdmi接口输出的分辨率
1. 先删除无用的文件: a) Boot/boot.src b) Boot/script.bin 2. 打开boot/script.fex,找到disp_init节点 a) 将screenX_outp ...
- Trianglify – 五彩缤纷的 SVG 背景图案
Trianglify 是一个能够生成五颜六色的三角形图案的 JavaScript 库,可以用来作为 SVG 图像和 CSS 背景.它的灵感来自于 Btmills 的 Geopattern,并使用 d3 ...
- POJ 3468 (线段树 区间增减) A Simple Problem with Integers
这题WA了好久,一直以为是lld和I64d的问题,后来发现是自己的pushdown函数写错了,说到底还是因为自己对线段树理解得不好. 因为是懒惰标记,所以只有在区间分开的时候才会将标记往下传递.更新和 ...
- 通过运行时动态给OC分类添加属性
#import <UIKit/UIKit.h> /** iOS 开发中,分类默认不允许保存属性 如果在分类中,定义一个属性,需要自己实现 getter & setter 方法,而且 ...
- Linux 系统时钟(date) 硬件时钟(hwclock)
/********************************************************************* * Linux 系统时钟(date) 硬件时钟(hwclo ...
- java中对浮点数精度的处理DecimalFormat
DecimalFormat是一个队浮点数进行格式化输出的利器,比如我们要输出一个保留一位小数的浮点数,可以键入如下代码: DecimalFormat df = new DecimalFormat(&q ...
- php排序测试
对 http://www.cnblogs.com/kudosharry/articles/2521621.html 这个补充的调用系统sort()函数的测试结果 1000个随机数: 直接插入排序:时间 ...
- HDU 查找最大元素 2025
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #defin ...