POJ 1523

做这题是因为这是我们作业......

题目意思很简单,求所有割点以及割开以后的点数

做法1:

nm的暴力直接上...

暴力割哪个点

是能过的.....

做法2:

二分+并查集

我们维护一个并查集,然后先把编号在[n/2,n]的边加进去

然后再dfs下去,每次加一些边,直到dfs到某个点为止

那么这样我们就可以统计出在每个点的时候一共合并了多少次并查集,复杂度O(alpha * m log n),

如果我们把并查集看成O(1)的那么就是O(m log n)

这个办法写起来挺麻烦的

做法3:

用tarjan来求双连通分量的那个算法跑一边

但是我们不再关心双连通分量,而是考察每个节点在dfs过去并回来的时候,low是否小于当前节点的dfn

如果是的,那么删除这个点以后,这个部分将会被割开

注意处理下根的情况

代码1:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct edge
{
    int y;
    edge * next;
};
edge * li[1005];
int top=0;
edge * new_edge()
{
    static edge a[1000005];
    return &a[top++];
}
void inserts(int x,int y)
{
    edge * t=new_edge();
    t->y=y;
    t->next=li[x];
    li[x]=t;
}
void insert_edge(int x,int y)
{
    inserts(x,y);
    inserts(y,x);
}
bool vis[1005];
void dfs(int x,int y)
{
    if (x==y)
    {
        return;
    }
    vis[x]=true;
    edge * t;
    for (t=li[x];t!=0;t=t->next)
    {
        if (vis[t->y])
        {
            continue;
        }
        if (t->y==y)
        {
            continue;
        }
        dfs(t->y,y);
    }
}
int a[1005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int zu;
    for (zu=1;;zu++)
    {
        top=0;
        memset(li,0,sizeof(li));
        int cnt=0;
        for (;;)
        {
            int x,y;
            scanf("%d",&x);
            if (x==0) break;
            scanf("%d",&y);
            x--;
            y--;
            a[cnt++]=x;
            a[cnt++]=y;
            insert_edge(x,y);
        }
        if (cnt==0)
        {
            break;
        }
        printf("Network #%d
",zu);
        sort(a,a+cnt);
        int n=unique(a,a+cnt)-a;
        memset(vis,0,sizeof(vis));
        int sum=0;
        int i;
        for (i=0;i<n;i++)
        {
            if (!vis[i])
            {
                dfs(i,-1);
                sum++;
            }
        }
        bool nospf=true;
        for (i=0;i<n;i++)
        {
            //destroy i
            int j;
            memset(vis,0,sizeof(vis));
            int sum2=0;
            for (j=0;j<n;j++)
            {
                if (j==i)
                {
                    continue;
                }
                if (!vis[j])
                {
                    dfs(a[j],a[i]);
                    sum2++;
                }
            }
            if (sum2>sum)
            {
                nospf=false;
                printf("  SPF node %d leaves %d subnets
",i+1,sum2);
            }
        }
        if (nospf)
        {
            puts("  No SPF nodes");
        }
        puts("");
    }
    return 0;
}

代码2:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct edge
{
    int y;
    edge * next;
};
edge * li[1005];
int top=0;
edge * new_edge()
{
    static edge a[1000005];
    return &a[top++];
}
void inserts(int x,int y)
{
    edge * t=new_edge();
    t->y=y;
    t->next=li[x];
    li[x]=t;
}
void insert_edge(int x,int y)
{
    inserts(x,y);
    inserts(y,x);
}
int a[1005];
int findroot(vector<int> &fa,int x)
{
    int root;
    for (root=x;fa[root]!=-1;root=fa[root]) ;
    int temp;
    for (;fa[x]!=-1;)
    {
        temp=fa[x];
        fa[x]=root;
        x=temp;
    }
    return root;
}
int u(vector<int> &fa,vector<int> &size,int x,int y)
{
    x=findroot(fa,x);
    y=findroot(fa,y);
    if (x==y)
    {
        return 0;
    }
    if (size[x]>size[y])
    {
        swap(x,y);
    }
    fa[x]=y;
    size[y]+=size[x];
    return 1;
}
bool inside(int l,int r,int x)
{
    if ((l<=x)&&(x<r))
    {
        return true;
    }
    return false;
}
int std_ans;
vector<pair<int,int> > output_ans;
void dfs(int l,int r,vector<int> fa,vector<int> size,int ans)
{
    if (l==r-1)
    {
        if (ans>std_ans)
        {
            output_ans.push_back(make_pair(l+1,ans));
        }
        return;
    }
    int mid=(l+r)/2;
    int i;
    vector<int> fa2=fa;
    vector<int> size2=size;
    int ans2=ans;
    for (i=mid;i<r;i++)
    {
        edge * t;
        for (t=li[i];t!=0;t=t->next)
        {
            if (inside(l,mid,t->y))
            {
                continue;
            }
            ans2-=u(fa2,size2,i,t->y);
        }
    }
    dfs(l,mid,fa2,size2,ans2);
    for (i=l;i<mid;i++)
    {
        edge * t;
        for (t=li[i];t!=0;t=t->next)
        {
            if (inside(mid,r,t->y))
            {
                continue;
            }
            ans-=u(fa,size,i,t->y);
        }
    }
    dfs(mid,r,fa,size,ans);
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int zu;
    for (zu=1;;zu++)
    {
        top=0;
        memset(li,0,sizeof(li));
        int cnt=0;
        for (;;)
        {
            int x,y;
            scanf("%d",&x);
            if (x==0) break;
            scanf("%d",&y);
            x--;
            y--;
            a[cnt++]=x;
            a[cnt++]=y;
            insert_edge(x,y);
        }
        if (cnt==0)
        {
            break;
        }
        printf("Network #%d
",zu);
        sort(a,a+cnt);
        int n=unique(a,a+cnt)-a;
        vector<int> fa,size;
        fa.resize(n);
        size.resize(n);
        int i;
        for (i=0;i<n;i++)
        {
            fa[i]=-1;
            size[i]=1;
        }
        std_ans=n;
        for (i=0;i<n;i++)
        {
            edge * t;
            for (t=li[i];t!=0;t=t->next)
            {
                std_ans-=u(fa,size,i,t->y);
            }
        }
        for (i=0;i<n;i++)
        {
            fa[i]=-1;
            size[i]=1;
        }
        output_ans.clear();
        dfs(0,n,fa,size,n-1);
        for (i=0;i<(int)output_ans.size();i++)
        {
            printf("  SPF node %d leaves %d subnets
",output_ans[i].first,output_ans[i].second);
        }
        if (output_ans.size()==0)
        {
            puts("  No SPF nodes");
        }
        puts("");
    }
    return 0;
}

代码3:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct edge
{
    int y;
    edge * next;
};
edge * li[1005];
int top=0;
edge * new_edge()
{
    static edge a[1000005];
    return &a[top++];
}
void inserts(int x,int y)
{
    edge * t=new_edge();
    t->y=y;
    t->next=li[x];
    li[x]=t;
}
int ans[1005];
void insert_edge(int x,int y)
{
    inserts(x,y);
    inserts(y,x);
}
bool inque[1005];
int dfn[1005];
int low[1005];
int val=0;
void scc(int x)
{
    dfn[x]=val++;
    low[x]=dfn[x];
    inque[x]=true;
    edge * t;
    for (t=li[x];t!=0;t=t->next)
    {
        if (dfn[t->y]==-1)
        {
            scc(t->y);
            if (low[t->y]>=dfn[x])
            {
                ans[x]++;
            }
            low[x]=min(low[x],low[t->y]);
        }
        else if (inque[t->y])
        {
            low[x]=min(low[x],dfn[t->y]);
        }
    }
}
int a[1005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int zu;
    for (zu=1;;zu++)
    {
        top=0;
        memset(li,0,sizeof(li));
        int cnt=0;
        for (;;)
        {
            int x,y;
            scanf("%d",&x);
            if (x==0) break;
            scanf("%d",&y);
            x--;
            y--;
            a[cnt++]=x;
            a[cnt++]=y;
            insert_edge(x,y);
        }
        if (cnt==0)
        {
            break;
        }
        printf("Network #%d
",zu);
        sort(a,a+cnt);
        int n=unique(a,a+cnt)-a;
        memset(dfn,-1,sizeof(dfn));
        memset(ans,0,sizeof(ans));
        memset(inque,0,sizeof(inque));
        val=0;
        int i;
        int cnts=0;
        for (i=0;i<n;i++)
        {
            if (dfn[i]==-1)
            {
                cnts++;
                scc(i);
                ans[i]--;
            }
        }
        bool nospf=true;
        for (i=0;i<n;i++)
        {
            if (ans[i]>0)
            {
                nospf=false;
                printf("  SPF node %d leaves %d subnets
",i+1,ans[i]+cnts);
            }
        }
        if (nospf)
        {
            puts("  No SPF nodes");
        }
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/absi2011/p/9964530.html