POJ 2942 Knights of The Round Table

題目傳送門

分析:這道題涉及的知識太多了。。要徹底喫透可能還需要幾天。分享一篇題解。ps:是時候看看算法書了。

代碼

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include <vector>
using namespace std;

class POJ{
public:
    POJ(int _n,int _m):n(_n),m(_m){
        input();
        initia();
        buildG();
        solve();
    }
    struct Edge{
        int v;
        int next;
    };
    void input();
    void initia();
    void solve();
    void buildG();
    void Tarjan(int,int);
    void addEdge(int,int);
    bool isBinaryG(int,int);
    ~POJ(){
        int ans=0;
        for(int i=1;i<=n;++i){
            if(!canSettl[i]) ++ans;
        }
        cout<<ans<<endl;
        delete[] vis;
        delete[] hate;
        delete[] dfn;
        delete[] flag;
        delete[] color;
        delete[] low;
        delete[] edges;
        delete[] head;
        delete[] canSettl;
    }
private:
    int n,m;
    stack<int> s;
    bool* vis;
    bool** hate;
    int* dfn;
    bool* flag;
    int* low;
    int* color;
    int* head;
    Edge* edges;
    bool* canSettl;
    int cnt;
    int time;
    vector<int> connG;
};

void POJ::input(){
    int N=n+1;
    hate=new bool*[N];
    for(int i=1;i<N;++i){
        hate[i]=new bool[N];
        memset(hate[i],false,sizeof(bool)*N);
    }
    int a,b;
    while(m--){
        scanf("%d %d",&a,&b);
        hate[a][b]=true;
        hate[b][a]=true;
    }
}

void POJ::initia(){
    int N=n+1;
    int MAXE=2e6+5;
    dfn=new int[N];
    low=new int[N];
    flag=new bool[N];
    head=new int[N];
    vis=new bool[N];
    edges=new Edge[MAXE];
    color=new int[N];
    canSettl=new bool[N];
    memset(canSettl,false,sizeof(bool)*N);
    memset(vis,false,sizeof(bool)*N);
    memset(dfn,0,sizeof(int)*N);
    memset(low,0,sizeof(int)*N);
    memset(head,-1,sizeof(int)*N);
    cnt=0;
    time=1;
}

void POJ::addEdge(int u,int v){
    edges[cnt].v=v;
    edges[cnt].next=head[u];
    head[u]=cnt++;
}

void POJ::buildG(){
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            if(!hate[i][j]&&i!=j){
                addEdge(i,j);
            }
        }
    }
}

void POJ::solve(){
    for(int i=1;i<=n;++i){
        if(!vis[i]){
            Tarjan(i,0);
        }
    }
}

void POJ::Tarjan(int u,int fa){
    dfn[u]=low[u]=time++;
    s.push(u);
    vis[u]=true;
    for(int i=head[u];i!=-1;i=edges[i].next){
        int v=edges[i].v;
        if(v==fa) continue;
        if(!vis[v]){
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<=low[v]){
                memset(flag,false,sizeof(bool)*(n+1));
                memset(color,-1,sizeof(int)*(n+1));
                connG.clear();
                connG.push_back(u);
                int temp;
                do{
                    temp=s.top();
                    connG.push_back(temp);
                    flag[temp]=true;
                    s.pop();
                }while(temp!=v);
                flag[u]=true;
                if(!isBinaryG(u,0)){
                    int vertN=connG.size();
                    for(int i=0;i<vertN;++i){
                        canSettl[connG[i]]=true;
                    }
                }
            }
        }
        else low[u]=min(low[u],dfn[v]);
    }
}

bool POJ::isBinaryG(int u,int c){
    color[u]=c;
    for(int i=head[u];i!=-1;i=edges[i].next){
        int v=edges[i].v;
        if(!flag[v]) continue;
        if(color[v]==-1){
            if(!isBinaryG(v,c^1)) return false;
        }
        else if(color[u]==color[v]) return false;
    }
    return true;
}

int main(){
    int n,m;
    while(cin>>n>>m,n||m){
        POJ _2942(n,m);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章