tjut 4612

来源:互联网 发布:天敏t2网络机顶盒 编辑:程序博客网 时间:2024/05/16 05:53
#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<iostream>#include<cstring>const int VM = 200005;const int EM = 1000005;struct Edeg{    int to,nxt,vis;}edge[EM<<1],tree[EM<<1];int head[VM],vis[VM],thead[VM];int dfn[VM],low[VM],stack[VM],belong[VM];int ep,bridge,son,maxn,src,n,cnt,scc,top;int max (int a,int b){    return a > b ? a : b;}int min(int a ,int b){    return a > b ? b : a;}void addedge (int cu,int cv){    edge[ep].to = cv;    edge[ep].vis = 0;    edge[ep].nxt = head[cu];    head[cu] = ep ++;    edge[ep].to = cu;    edge[ep].vis = 0;    edge[ep].nxt = head[cv];    head[cv] = ep ++;}void Buildtree(int cu,int cv){    tree[son].to = cv;    tree[son].nxt = thead[cu];    thead[cu] = son ++;}void Tarjan (int u){    int v;    vis[u] = 1;    dfn[u] = low[u] = ++cnt;    stack[top++] = u;    for (int i = head[u];i != -1;i = edge[i].nxt)    {        v = edge[i].to;        if (edge[i].vis) continue; //        edge[i].vis = edge[i^1].vis = 1; //正向边访问过了,反向边得标志,否则两点会成一块。        if (vis[v] == 1)            low[u] = min(low[u],dfn[v]);        if (!vis[v])        {            Tarjan (v);            low[u] = min(low[u],low[v]);            if (low[v] > dfn[u])                bridge ++;        }    }    if (dfn[u] == low[u])    {        ++scc;        do{            v = stack[--top];            vis[v] = 0;            belong[v] = scc;        }while (u != v);    }}void BFS(int u){    int que[VM+100];    int front ,rear,i,v;    front = rear = 0;    memset (vis,0,sizeof(vis));    que[rear++] = u;    vis[u] = 1;    while (front != rear)    {        u = que[front ++];        front = front % (n+1);        for (i = thead[u];i != -1;i = tree[i].nxt)        {            v = tree[i].to;            if (vis[v]) continue;            vis[v] = 1;            que[rear++] = v;            rear = rear%(n+1);        }    }    src = que[--rear];//求出其中一个端点}void DFS (int u,int dep){    maxn = max (maxn,dep);    vis[u] = 1;    for (int i = thead[u]; i != -1; i = tree[i].nxt)    {        int v = tree[i].to;        if (!vis[v])            DFS (v,dep+1);    }}void solve(){    int u,v;    memset (vis,0,sizeof(vis));    cnt = bridge = scc = top = 0;    Tarjan (1);    memset (thead,-1,sizeof(thead));    son = 0;    for (u = 1;u <= n;u ++)              //重构图        for (int i = head[u];i != -1;i = edge[i].nxt)        {            v = edge[i].to;            if (belong[u]!=belong[v])            {                Buildtree (belong[u],belong[v]);                Buildtree (belong[v],belong[u]);            }        }    maxn = 0;    //最长直径    BFS(1);      //求树直径的一个端点    memset (vis,0,sizeof(vis));    DFS(src,0); //求树的最长直径    printf ("%d\n",bridge-maxn);}int main (){#ifdef LOCAL    freopen ("in.txt","r",stdin);#endif    int m,u,v;    while (~scanf ("%d%d",&n,&m))    {        if (n == 0&&m == 0)            break;        memset (head,-1,sizeof(head));        ep = 0;        while (m --)        {            scanf ("%d%d",&u,&v);            addedge (u,v);        }        solve();    }    return 0;}

0 0
原创粉丝点击