ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ-2942 Knights of the Round Table

2021-12-10 20:00:54  阅读:144  来源: 互联网

标签:include int maxn Table POJ Knights 骑士 now define


题意:一些骑士要进行圆桌会议,每桌要坐奇数个人。互相憎恨的骑士不能相邻。现给出骑士之间的憎恨关系(双向),求删去多少人后,能正常开会。

解:将互相不憎恨的骑士连边,也就是补图。注意每个骑士一定不憎恨他自己(离散数学老师:和自己达成和解,这样挺好的)想想下学期就不能听他扯淡了还有点难过,一定不要连自环,在这WA了好几次。因为要坐成一个圆,所以在图上找大于等于3的环。找环用tarjan,但找到了环不能确定它的大小,因为可以偶数环里套奇数环,所以还要判断一下这些点里有没有奇数环,可以用染色,如果一个点将染两种不同的颜色,那就有奇环了。二分图判断也是用的这个方法。

现在来具体实现。首先无向图tarjan找环和有向图是不同的,因为会找到父亲那里,所以要多传一个参数,特判一下(注意这道题没有重边,所以可以直接判)。找环的第一个点,也就是割点的判断条件,dfn[now]<=low[to],然后从栈里把这个环拿出来,判一下奇偶。第一个点不要弹出栈,因为还要找下一条边。

代码:

#include <algorithm>
#include <stack>
#include <vector>
#include <stdio.h>
using namespace std;
#define maxx 10005
#define maxn 1005
#define maxm 5000005
#define inf 0x3f3f3f3f
int n,m;
vector<int> e[maxn];
int dfn[maxn]={0},low[maxn]={0};
int cnt=0,vis[maxn]={0};
int cir[maxn],is[maxn];
int bel[maxn],color[maxn],belnum;
int mp[maxn][maxn];
stack<int> s;
int dfs(int now,int col){
    color[now]=col;
    for(int i=0;i<e[now].size();i++){
        int to=e[now][i];
        if(bel[to]!=bel[now])
            continue;
        if(!color[to]&&dfs(to,-col))
            return 1;
        if(color[to]==col)
            return 1;
    }
    return 0;
}
void tarjan(int now,int fa){
    s.push(now);
    vis[now]=1;
    low[now]=dfn[now]=++cnt;
    for(int i=0;i<e[now].size();i++){
        int to=e[now][i];
        if(to==fa)
            continue;
        if(!dfn[to]){
            tarjan(to,now);
            low[now]=min(low[now],low[to]);
            if(dfn[now]<=low[to]){
                int num=0;
                belnum++;
                while(1){
                    int t=s.top();
                    s.pop();
                    vis[t]=0;
                    bel[t]=belnum;
                    cir[++num]=t;
                    if(t==to)
                        break;
                }
                cir[++num]=now;
                bel[now]=belnum;
                memset(color,0,sizeof color);
                if(num>=3&&dfs(now,1)){
                    for(int j=1;j<=num;j++)
                        is[cir[j]]=1;
                }
            }
        }
        else if(vis[to])
            low[now]=min(low[now],dfn[to]);
    }
}
void init(){
    memset(dfn,0,sizeof dfn);
    memset(low,0,sizeof low);
    memset(vis,0,sizeof vis);
    memset(e,0,sizeof e);
    memset(mp,0,sizeof mp);
    memset(is,0,sizeof is);
    memset(bel,0,sizeof bel);
    cnt=0;belnum=0;
    while(!s.empty())
        s.pop();
}
signed main() {
    while(~scanf("%d%d",&n,&m)){
        if(n==0&&m==0)
            break;
        init();
        for(int i=0;i<m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            mp[x][y]=1;
            mp[y][x]=1;
        }
        for(int i=1;i<=n;i++) {
            for (int j = 1; j <= n; j++)
                if (!mp[i][j]&&i!=j)
                    e[i].push_back(j);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i])
                tarjan(i,0);
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            if(is[i])
                ans++;
        }
        ans=n-ans;
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

标签:include,int,maxn,Table,POJ,Knights,骑士,now,define
来源: https://www.cnblogs.com/capterlliar/p/15673636.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有