CodeForces Round #111 Div.2 problem D 160D

來源:互聯網
上載者:User
/*題意:最小產生樹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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.