Codeforces 160D Edges in MST

来源:互联网 发布:一口气英语软件下载 编辑:程序博客网 时间:2024/05/01 01:10

给你一幅图,对于图中的每一条边,判断

1、存在于任何一棵最小生成树中 any

2、至少存在于某一棵最小生成树中  at least one

3、不存在任何一棵最小生成树中 none

把边权按从小到大进行排序,每次对相同边权的边进行集中处理。

第一次集中处理:若两点已在同一集合内,则此边为(none);否则标记为(at least one),并建边。

第二次集中处理:对标记为at least one)的边进行的dfs,判断是否为桥,若是桥,则标记为(any)。

第三次集中处理:合并点并初始化前两步所用到的数组。


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int MAXN=100005;int n,m;struct Edge{    int x,y,val,id,ans;    bool operator < (const Edge& a) const    {        return val<a.val;    }}e[MAXN];struct E{    int v,next,id;}edge[MAXN*2];int fa[MAXN];int low[MAXN],dep[MAXN];int head[MAXN],len;int mark[MAXN];int com[MAXN];char res[][20]={"none","any","at least one"};void add_edge(int u,int v,int id){    edge[len].v=v;    edge[len].id=id;    edge[len].next=head[u];    head[u]=len++;}int find(int x){    return fa[x]==x?x:fa[x]=find(fa[x]);}bool cmp(Edge a,Edge b){    return a.id<b.id;}void dfs(int u,int father,int depth){    int i;    mark[u]=1;    low[u]=dep[u]=depth;    for(i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(mark[v]==1&&edge[i].id!=father&&dep[v]<low[u])            low[u]=dep[v];        else if(mark[v]==0)        {            dfs(v,edge[i].id,depth+1);            if(low[v]<low[u])                low[u]=low[v];            if(low[v]>dep[u])//这条边是桥                e[edge[i].id].ans=1;        }    }    mark[u]=2;}int main(){    int i,j,x,y;    scanf("%d%d",&n,&m);    for(i=0;i<=n;i++)        fa[i]=i;    for(i=0;i<m;i++)    {        scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].val);        e[i].id=i;        e[i].ans=0;    }    sort(e,e+m);    memset(head,-1,sizeof(head));    len=0;    for(i=0;i<m;)    {        int s=i;        while(i<m&&e[i].val==e[s].val)            i++;        for(j=s;j<i;j++)        {            x=find(e[j].x);            y=find(e[j].y);            if(x==y)                continue;            e[j].ans=2;            add_edge(x,y,j);            add_edge(y,x,j);            com[j]=x;        }        for(j=s;j<i;j++)        {            if(com[j]&&!mark[com[j]])                dfs(com[j],0,1);        }        for(j=s;j<i;j++)        {            x=find(e[j].x);            y=find(e[j].y);            head[x]=-1;            head[y]=-1;            mark[x]=0;            mark[y]=0;            if(x==y)                continue;            fa[x]=y;        }        len=0;    }    sort(e,e+m,cmp);    for(i=0;i<m;i++)        printf("%s\n",res[e[i].ans]);    return 0;}


原创粉丝点击