• zoj2588 Burning Bridges --- 寻求尖端




    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <map>
    #define inf 0x3f3f3f3f
    #define eps 1e-6
    #define ll __int64
    using namespace std;
    #define N 10010
    #define M 100010
    
    struct node//边结点
    {
        int v,tag,id;//v为所连接的还有一个结点。tag为重边数,id为序号
        node *next;
    };
    int n,m;//点,边数
    int nid;//输入时边的序号
    node mem[M*2];int memp;//mem为存储边结点的数组,memp为mem数组序号
    node *e[N];//邻接表
    int brig[M];//brig[i]=1表示第i+1条边为割边
    int nbrig;//求得割边的数目
    int low[N],dfn[N];//low[i]为顶点i可达祖先的最小编号。dfn[i]为深度优先数
    int vis[N];//0未訪问 1已訪问 2已訪问且已检查邻接结点
    
    //在邻接表中插入边(i,j)。若有重边。则仅仅把对应边结点的tag+1
    int addedge(int i,int j)
    {
        node* p;
        for(p=e[i];p!=NULL;p=p->next)
            if(p->v==j) break;
        if(p!=NULL)
        {
            p->tag++;
            return 0;
        }
        p=&mem[memp++];
        p->v=j;
        p->next=e[i];
        e[i]=p;
        p->id=nid;
        p->tag=0;
        return 1;
    }
    
    //參数含义:i为当前搜索的顶点。father为i的父节点。dth为搜索深度
    void dfs(int i,int father,int dth)
    {
        vis[i]=1;
        dfn[i]=low[i]=dth;
        node* p;
        for(p=e[i];p!=NULL;p=p->next)
        {
            int j=p->v;
            if(j!=father&&vis[j])
                low[i]=min(low[i],dfn[j]);
            if(!vis[j])
            {
                dfs(j,i,dth+1);
                low[i]=min(low[i],low[j]);
                if(low[j]>dfn[i]&&!p->tag)
                    brig[p->id]=++nbrig;
    
            }
        }
        vis[i]=2;
    }
    
    void init()
    {
        memp=nid=nbrig=0;
        memset(e,0,sizeof e);
        memset(brig,0,sizeof brig);
        memset(vis,0,sizeof vis);
    }
    
    int main()
    {
        int t,i,j,a,b;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            init();
            for(i=0;i<m;i++)
            {
                scanf("%d%d",&a,&b);
                addedge(a-1,b-1);
                addedge(b-1,a-1);
                nid++;
            }
            dfs(0,-1,1);
            printf("%d
    ",nbrig);
            for(i=0,j=nbrig;i<m;i++)
            {
               // printf("i:%d brig[i]:%d
    ",i+1,brig[i]);
                if(brig[i])
                {
                    printf("%d",i+1);
                    if(--j) putchar(' ');
                }
            }
            if(nbrig) puts("");
            if(t) puts("");
        }
        return 0;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    程序多开原理记录
    BitTorrent协议规范(BitTorrent Protocol Specification)之Tracker HTTP/HTTPS Protocol第三部分
    到底什么是RBD?
    关于missing unit proxies.pas
    教你简单去除 Office 2007 盗版提示
    手把手教你使用WINDBG KO XXXX游戏驱动保护
    c# 模拟提交有附件表单(转)
    常用断点(OD中)
    delphi中Webbrowser
    PS3简易蓝光规格视频制作说明
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4683249.html
Copyright © 2020-2023  润新知