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 ...
随机推荐
- Python3 学习第十弹: 模块学习三之数字处理
math模块 提供基础的数学函数, cos(3.14) = -0.999..(弧度制) acos(1) = 0.0 sqrt(9) = 3.0 degrees(3.14) = 179.9999..(弧 ...
- Jquery源码中的Javascript基础知识(三)
这篇主要说一下在源码中jquery对象是怎样设计实现的,下面是相关代码的简化版本: (function( window, undefined ) { // code 定义变量 jQuery = fun ...
- spring、springmvc、mybatis整合笔记
这段时间上一个项目刚做完,下一个项目还没开始,趁这个时候来认真总结一下上个项目使用的ssm开发框架.由于,项目中关于使用ssm这部分的代码和配置是我们项目的整体架构师一个独立完成的,我们只负责业务部分 ...
- aspose.words复制插入同一word文档中的某个页面
选择word模板 Document doc = new Document(Server.MapPath("~\\templet") + "\\" + name. ...
- js sleep效果
js sleep效果 s = setInterval(function(){ //需要执行的函数 alert("我延迟了2秒弹出"); },2000); 并不是每2秒执行一次,而是 ...
- Arduino命令行编译 树莓派连接Arduino 电脑上编译Arduino代码后 通过树莓派烧写到Arduino上
//本教程针对UNO 1.在file->preferences中找到preferences.txt文件 2:用记事本打开preferences.txt,选择hex文件存放的路径,在最后行加入 b ...
- cong
Directions: Study the following cartoon carefully and write an essay in which you should 1) descr ...
- C++静态成员总结(转)
类中的静态成员真是个让人爱恨交加的特性.我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动. 静态类成员包括静态数据成员和静态函数成员两部分. 一 静态数据成员: 类体中 ...
- cp: omitting directory”错误的解释和解决办法
在linux下拷贝的时候有时候会出现cp:omitting directory的错误 ,例如 cp:omitting directory "bbs" 说明bbs目录下面还有目录,不 ...
- ScrollView中嵌套ListView
scrollview中嵌入listview,要是直接把listview嵌进scrollview中,listview的高度是固定的不能进行滑动.默认情况下Android是禁止在ScrollView中放入 ...