poj1515Street Directions【无向图->有向图 链式前向星版tarjan求桥】

原创 2015年11月20日 13:32:03

纠结半天怎么用原来的模板表示边与序号的关系,map都用上了,还是一塌糊涂,然而,这是图啊……怎么能把链式前向星忘了→_→

具体看注释 ,思路当然和那些都一样

/***********
poj1515
2015.11.20
796K	157MS	G++	2230B
***********/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>

using namespace std;

const int MAXN=1111;

struct Edge
{
    int v,next;
    bool vis;
}edge[MAXN*MAXN];
int n,m,NE;
int head[MAXN];

void Insert(int u,int v)
{
    edge[NE].v=v;
    edge[NE].next=head[u];
    edge[NE].vis=false;
    head[u]=NE++;
}

int cnt,_count;
int low[MAXN],dfn[MAXN],color[MAXN];
bool mark[MAXN];
stack<int>S;
void Tarjan(int u,int father)
{
    int flag=0;
    low[u]=dfn[u]=++cnt;
    mark[u]=true;
    S.push(u);
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==father&&!flag)
        {
            flag=1;
            continue;
        }
        if(dfn[v]==0)
        {
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
        }
        else if(mark[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u])
    {
        int v;
        _count++;
        do{
            v=S.top();
            S.pop();
            mark[v]=false;
            color[v]=_count;//标记每个点所在的集合序号
        }while(u!=v);
    }
}
void Solve(int u,int father)
{
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==father) continue;
        if(color[u]==color[v]&&!edge[i].vis)
            printf("%d %d\n",u,v);//因为在同一个连通分量中 双向的边输出一个方向的就好
        else if(color[u]!=color[v]&&!edge[i].vis)
        {
            printf("%d %d\n",u,v);
            printf("%d %d\n",v,u);//因为是桥 所以输出双向的
        }
        edge[i].vis=true;
        edge[i^1].vis=true;//不管是输出了单向的还是双向的 这条边都结束了
        if(!mark[v])
        {
            mark[v]=true;
            Solve(v,u);
        }
    }
}
int main()
{
   // freopen("cin.txt","r",stdin);
    int u,v,t=1;
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0) break;
        NE=0;
        memset(head,-1,sizeof(head));
        while(m--)
        {
            scanf("%d%d",&u,&v);
            Insert(u,v);
            Insert(v,u);

        }
        cnt=_count=0;
        memset(dfn,0,sizeof(dfn));
        memset(mark,false,sizeof(mark));
        Tarjan(1,-1);
        printf("%d\n\n",t++);
        memset(mark,false,sizeof(mark));
        mark[1]=true;
        Solve(1,-1);
        puts("#");
    }
    return 0;
}




版权声明:⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄hiahiahia 欢迎斧正 举报

相关文章推荐

poj 1515 Street Directions(无向图改有向图)

Street Directions Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 586   Accepted:...

uva610 Street Directions(无向图桥的应用)

题意有一张道路交通图,每条边都是双向的,且连通。现在想尽量把一些多的道路改成单向的,且任意两点是可达的,输出改造后的道路图。 分析同一个双连通分量里面的边都是可以通过重定向使得相互可达,可以改成单向边...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

POJ 1515 Street Directions

题意: 一幅无向图  将尽量多的无向边定向成有向边  使得图强连通  无向图保证是连通的且没有重边 思路: 桥必须是双向的  因此先求边双连通分量  并将桥保存在ans中 每个双连通分量内的边...

poj 1515 Street Directions(双连通分量)

题意:给出一个连通图,边是双向边,要求令尽可能多的双向边改成单向边,并且图还是连通的(强连通)。 思路:这题其实不太难搞。我们可以想一下,那些边是一定不能改造的?没错,是桥,如果桥被改成单向边,那么...

POJ 3694 network 无向图求桥 手写栈版tarjan

这题以前做过 大意就是给出一个无向图,然后每次询问加一条边,然后输出当前图中剩余的桥的个数 大概做法就是先tarjan把桥都弄出来,然后每次加边就裸求LCA。 不过很蛋疼的事情就是在HDU上会爆栈,这...

poj3694 Network 无向图tarjan求桥+LCA

Language: Default Network Time Limit: 5000MS   Memory Limit: 65536K Total Submis...

无向图和有向图关于连通性的tarjan算法

无向图的割顶,桥和构造双连通分量以及有向图的极大连通分量,相关概念看这里 http://www.byvoid.com/blog/biconnect/ 程序部分自己写,理论部分参考上方链接。 根据黑...

POJ 1144 Network 无向图求割点Tarjan

题目描述:Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They...

poj 2117(tarjan 求无向图去掉一点的连通分量)

题意:在一片森林中求去掉一节点之后形成最多的连通分量的个数。注意是森林就可以了。 #include #include #include #define min(a,b) ((a)(b...

poj1144Network 无向图求割点Tarjan

n个点,组成一个无向图,求这个图中割点的数量。模板题。 只是这道题在输入数据的时候有点麻烦,如样例中,第一组数据有五个点,5 1 2 3 4 表示5这个点与1 2 3 4 点相连。其中这个图的割点...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)