`
hududumo
  • 浏览: 238398 次
文章分类
社区版块
存档分类
最新评论

CodeForces Round #111 Div.2 problem D 160D

 
阅读更多
/*
题意:
最小生成树and tarjan.
给定一个简单无向连通图G(v,e),他的最小生成树为T(不一定唯一),
对于图中的任意一条边,如果它不可能在T中,输出none,
如果它一定在T中,输出any
如果它可能在T中,输出at least one

题解:
只有有相同权值的边的时候才可能出现at least one的情况
G的点集为N
如果 e1,e2,e3...的权值相同,在N中以克鲁斯卡尔算法的方式加入所有边权小于e1的边(这个时候出现一些联通分量)
把这些连通分量抽象成点(这一点并查集可以做到),那么出现一个新的图Y(一定无环),这Y中也以鲁斯卡尔算法的方式加入e1,e2, e3....(没加入的肯定是连通分量内部的边,必然为none),如果出现环(包括两条重边构成的环),那么这些加入的e必然是at least one,因为可以通过破环把其中之一剔除出最小生成树,其他的必然为any(这些是新图Y的割边)。
*/
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <cstdio>
#include <vector>
using namespace std;
const int N=100009;
struct Edge 
{
    int u,v,w,ans,id;
    bool operator<(const Edge &y) const
    {
        return this->w<y.w;
    }
}e[N];
int n,m;
bool cmp(Edge x,Edge y)
{
    return x.id<y.id;
}
map<int,vector<int> > v,mark;
map<int,int> vis,first;
set<int> Set;
int fa[N],tim;
char res[][20]={"none","at least one","any"};
int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void tarjan(int x)
{
    if(vis[x])return ;
    vis[x]=first[x]=++tim;
    for(int i=0;i<v[x].size();i++)
    {
        int y=v[x][i];
        int Mark=mark[x][i];
        if(Set.count(Mark))continue;//记录边是否访问过,漏掉重边构成的环
        Set.insert(Mark);
        tarjan(y);
        if(vis[y]<vis[x])
        {
            vis[x]=vis[y];
        }
        if(vis[y]>first[x])//找到割边
        {
            e[Mark].ans=2;
        }
    }
}
int main() {
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=0;i<=n;i++)fa[i]=i;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
            e[i].ans=0;
            e[i].id=i;
        }
        sort(e,e+m);
        for(int i=0;i<m;)
        {
            int s=i,x,y;
            while(i<m&&e[i].w==e[s].w) i++;//挑出一段相同边权的边
            v.clear();
            vis.clear();
            mark.clear();
            Set.clear();
            for(int j=s;j<i;j++)
            {
                x=find(e[j].u);
                y=find(e[j].v);
                if(x==y)continue;
                e[j].ans=1;
                v[x].push_back(y);
                v[y].push_back(x);
                mark[x].push_back(j);//记录两点间边的编号
                mark[y].push_back(j);
            }
            for(map<int,vector<int> >::iterator it=v.begin();it!=v.end();it++)
            {
                tarjan(it->first);
            }
            for(int j=s;j<i;j++)
            {
                x=find(e[j].u);
                y=find(e[j].v);
                if(x==y)continue;
                fa[x]=y;
            }
        }
        sort(e,e+m,cmp);
        for(int i=0;i<m;i++)
        {
            printf("%s\n",res[e[i].ans]);
        }
    }
    return 0;
}

分享到:
评论

相关推荐

    Codeforces Round #723 (Div. 2).md

    Codeforces Round #723 (Div. 2).md

    Codeforces Round #630 (Div. 2) D. Walk on Matrix(构造)

    上面代码跑出来的dp[n][m]是0,然后从(1,1)(1,2)(2,2)(2,3)这样的相与值是k (看懂ans+k是啥应该就懂了) 代码: int main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int ans=(1&...

    Codeforces Round #627 (Div. 3) B. Yet Another Palindrome Problem

    就是把所有相等的数放到一个vector里,如果他出现大于2次,看最远的间距是否大于2即可,找到一个就可以 代码: #include #include #include #include #include #include #include #include #include #include #...

    Codeforces Round #627 (Div. 3) C. Frog Jumps(思维)

    每步只能跳d 在1——n每个位置有方向,L,R,求d的最小值 思路: 只用找相邻两个R之间的最大值即可 代码: #include #include #include #include #include #include #include #include #include #include #define ...

    Codeforces Round #629 (Div. 3) B. K-th Beautiful String

    长度为n的字符串包含n−2n−2n−2个aaa和222个bbb,求按照字典序排列输出第kkk个字符串 解题思路 第一个bbb在倒数第二位有1个字符串,在倒数第三位有2个字符串…在倒数第nnn位时有n−1n-1n−1个字符串 可以根据第一...

    Codeforces Round #479 (Div. 3) E. Cyclic Components

    E. Cyclic Components 题目链接-E. Cyclic Components 题目大意 给你nnn个点和mmm条边,求所构成图中单圈环的个数 ...并查集并查集并查集 很明显单圈环每个点的度都为222,所以我们可以用数组cnt[]记录每个点的度,...

    Codeforces Round #629 (Div. 3) E.Tree Queries (DFS)

    Codeforces Round #629 (Div. 3) E.Tree Queries (DFS) 思路:若ai 在路径上 ,则ai的父结点一定在路径上,若ai是路径上某个结点的子结点,则ai的父结点一定在路径上,综上只需考虑ai的父节点就行了。对每个ai判断...

    Codeforces Round #635 (Div. 2)D. Xenia and Colorful Gems

    传说门 刚好今晚是中国场! 其实这道题比较水,但当时思路错,一心想着化简公式,浪费了好多时间a....#pragma GCC optimize(2) #include #define ll long long #define endl '\n' using namespace std; const int manx=

    Codeforces Round #628 (Div. 2)

    给两两节点放一个数字(0~n-2 唯一) 给你一棵树,求所有任意两节点相连的路以外的路上的数字的最小值最小 思路 构造 若一个点连了三条边及以上,则这个点的边从最小值开始赋值。其他边从最大点开始赋值。 证明:一...

    Codeforces Round #627 (Div. 3) A. Yet Another Tetris Problem

    给一个长度为n的数组,两种操作,一个是把任意一个ai变成ai+2a_i变成a_i+2ai​变成ai​+2,另一个是如果所有数都大于0,可以把所有数减1,问通过这些操作能否把所有数变为0 思路: 如果任意两个数之差为奇数,那么就...

    Codeforces Round #620 (Div. 2) Longest Palindrome

    B. Longest Palindrome ...Returning back to problem solving, Gildong is now studying about palindromes. He learned that a palindrome is a string that is the same as its reverse. For example, strings

    Codeforces Round #627 (Div. 3)B. Yet Another Palindrome Problem

    Yet Another Palindrome Problem 题目链接-B. Yet Another Palindrome Problem 题目大意 给一个长为n(≤5000)的数组,问是否存在一个长度至少为3的子序列是回文的,子序列的数可以不连续但是相对顺序不可变 解题...

    Codeforces Round #628 (Div. 2) A~~D

    A #include using namespace std; typedef long long ll; int main(){ int t; cin&gt;&gt;t; while(t--){ ll x; cin&gt;&gt;x; cout&lt;&lt;1&gt;&gt;t; while(t--){ st.clear(); ll n; cin &gt;&gt;n;... ll re

    Codeforces Round #628 (Div. 2) D. Ehab the Xorcist(异或构造,思维)

    传送门 题意: 给两个整数u,v,构造一个数组,使得数组的异或和等于u,数组的和等于v 要求构造的数组尽可能的短 思路: 对于每种情况讨论输出即可,注意几种情况的特判 看代码应该能明白 代码: ...

    Codeforces Round #628 (Div. 2) A. EhAb AnD gCd

    输入一个正整数x,找出这样的2个正整数a和b,使得gcd(a,b)+lcm(a,b)=x 解题思路 找最特殊的情况a=1,b=x-1即可 这样a,b两个数最大公因数为1,最小公倍数x-1,满足题意√ 附上代码 #include #define int long long #...

    Codeforces Round #628 (Div. 2)【A B C D】

    传送门 A. EhAb AnD gCd 直接输出1,n-1即可 #include #include #include #include #include #include #include #include #include #include #define pb push_back #define lb lower_bound ...con

    Codeforces Round #633 (Div. 2) A. Filling Diamonds(找规律)

    传送门 题意: 找规律,题意就是有多少种方式填充该图形 画两个就发现,输出n即可 代码: #include #include #include #include #include #include #include #include ...#define SZ(x) ((int)(x)

    Educational Codeforces Round 83 (Rated for Div. 2) D

    今天CF被D恶心到了,写个题解重新整理下思路,(20开始想,25写完暴力代码,1.30才过,优化后的。。 核心思路就是在暴力的基础上进行组合数等差加速。 C(n-2,i-1)*C(j-1,n-2)*(i-1) __ j: n-1 -&gt; m 我们发现内层...

    【Codeforces Round#620 (Div. 2)】B. Longest Palindrome 题解

    Returning back to problem solving, Gildong is now studying about palindromes. He learned that a palindrome is a string that is the same as its reverse. For example, strings “pop”, “noon”, “x”, ...

Global site tag (gtag.js) - Google Analytics