SDUT 2170 The Largest SCC(强连通+边的变换)

来源:互联网 发布:telnet 端口打开 编辑:程序博客网 时间:2024/05/21 07:12

大意:给定一个有向图,然后又有Q个询问,每次询问为k代表将第k次加的边转化为双向边。问最后的最大的联通块内的节点个数。


思路:在Q次询问的时候我们可以判断此边的端点是不是在一个联通分量中,是的话直接输出原来建图时找到的最大联通节点数,否则的话将当前Q[k].b的head值记录下来以便之后的删除改边,然后dfn[],和stk[]清除重新建图,再次求最大联通节点数即可。


#include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define LL int#define inf 0x3f3f3f3f#define eps 1e-8#include<vector>#define ls l,mid,rt<<1#define rs mid+1,r,rt<<1|1using namespace std;const int nv = 21000;const int ne = 51000;struct node{    int to,next;}q[ne<<1];struct N{    int a,b;}Q[40010];int head[ne<<1],dfn[nv],num[nv],in[nv],stk[nv],low[nv],maxpo;int cnt,top,tim,scc,out[nv],n,mi;bool vis[nv];void Add(int a,int b){    q[cnt].to = b;    q[cnt].next = head[a];    head[a] = cnt++;}void Tarjan(int u){    dfn[u] = low[u] = tim++;    stk[top++] = u;    vis[u] = 1;    for(int i = head[u];~i;i=q[i].next){        int v = q[i].to;        if(!dfn[v]){            Tarjan(v);            low[u] = min(low[u],low[v]);        }        else if(vis[v]){            low[u] = min(low[u],dfn[v]);        }    }    if(dfn[u]== low[u]){        scc++;        int tp = 0;        while(top>0&&stk[top] != u){            int now = stk[--top];            num[now] = scc;            tp++;            vis[now] = 0 ;        }        maxpo = max(maxpo,tp);    }}void init(){    maxpo = scc =  cnt = top = 0;    tim =  1;    memset(head,-1,sizeof(head));    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(vis,false,sizeof(vis));    memset(num,0,sizeof(num));}int main(){    int n,m,i,j,k,cla,a,b,T;    scanf("%d",&cla);    while( cla-- ){        init();        scanf("%d%d%d",&n,&m,&T);        for(i = 1;i <= m;++ i){            scanf("%d %d",&Q[i].a,&Q[i].b);            Add(Q[i].a,Q[i].b);        }        for(i = 1;i <= n;++ i)            if(!dfn[i])                Tarjan(i);        int pri = maxpo;        while(T--){            scanf("%d",&k);            if(num[Q[k].a ]==num[Q[k].b ]){                printf("%d\n",pri);continue;            }            memset(dfn,0,sizeof(dfn));            memset(stk,0,sizeof(stk));            tim =1;memset(vis,false,sizeof(vis));            maxpo = 0;            int newhead = head[ Q[k].b ];            Add(Q[k].b,Q[k].a);            for(i = 1;i <= n;++ i)                Tarjan(i);            printf("%d\n",max(pri,maxpo));            cnt -- ;            head[Q[k].b] = newhead;        }    }    return 0;}


0 0
原创粉丝点击