uva 1364 - Knights of the Round Table(点双连通分量,5级)

uva 1364 - Knights of the Round Table(二分图+强连通) 题目链接:uva 1364 - Knights of the Round Table 处理出所有点-双联通分量,判断每个联通分量是否是二分图,如果不是二分图的话所有点即为有会议可以参加。 #include #include #include #include #include using namespace std; typedef pair pii; const 阅读详情

Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very surprising that in recent years the kingdom of King Arthur has experienced an unprecedented increase in the number of knights. There are so many knights now, that it is very rare that every Knight of the Round Table can come at the same time to Camelot and sit around the round table; usually only a small group of the knights isthere, while the rest are busy doing heroic deeds around the country.

Knights can easily get over-excited during discussions-especially after a couple of drinks. After some unfortunate accidents, King Arthur asked the famous wizard Merlin to make sure that in the future no fights break out between the knights. After studying the problem carefully, Merlin realized that the fights can only be prevented if the knights are seated according to the following two rules:

  • The knights should be seated such that two knights who hate each other should not be neighbors at the table. (Merlin has a list that says who hates whom.) The knights are sitting around a roundtable, thus every knight has exactly two neighbors.
  • An odd number of knights should sit around the table. This ensures that if the knights cannot agree on something, then they can settle the issue by voting. (If the number of knights is even, then itcan happen that ``yes" and ``no" have the same number of votes, and the argument goes on.)

Merlin will let the knights sit down only if these two rules are satisfied, otherwise he cancels the meeting. (If only one knight shows up, then the meeting is canceled as well, as one person cannot sit around a table.) Merlin realized that this means that there can be knights who cannot be part of any seating arrangements that respect these rules, and these knights will never be able to sit at the Round Table (one such case is if a knight hates every other knight, but there are many other possible reasons). If a knight cannot sit at the Round Table, then he cannot be a member of the Knights of the Round Table and must be expelled from the order. These knights have to be transferred to a less-prestigious order, such as the Knights of the Square Table, the Knights of the Octagonal Table, or the Knights of the Banana-Shaped Table. To help Merlin, you have to write a program that will determine the number of knights that must be expelled.

Input 

The input contains several blocks of test cases. Each case begins with a line containing two integers 1$ \le$n$ \le$1000 and 1$ \le$m$ \le$1000000 . The number n is the number of knights. The next m lines describe which knight hates which knight. Each of these m lines contains two integers k1 and k2 , which means that knight numberk1 and knight number k2 hate each other (the numbers k1 and k2 are between 1 and n ).

The input is terminated by a block with n = m = 0 .

Output 

For each test case you have to output a single integer on a separate line: the number of knights that have to be expelled.

Sample Input 

5 5
1 4
1 5
2 5
3 4
4 5
0 0

Sample Output 

2

思路:只要存在奇环的点都符合条件,因此,求出点双连通分量,确定有环,再使用二分图判断是否为奇环就可以了。

          有一点要注意,求二分图判奇环标记,要使用在线算法,离线个人认为不行,(也许行吧,就是根点处理不好)


AC码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
using namespace std;
const int mm=1009;
const int mn=3e6+9;
class node
{
  public:int u,v,next,vis;
}e[mn];
int head[mm],edge;
bool mark[mn];
int dfn[mm],low[mm],dfs_clock,bcc_no,n,m;
int corlor[mm],vis_clock;
int stak[mn],top;
bool vis[mm],g[mm][mm];
void data()
{
  memset(head,-1,sizeof(head));
  memset(vis,0,sizeof(vis));
  memset(g,0,sizeof(g));
  edge=0;top=0;
}
void add(int u,int v)
{ e[edge].v=v;e[edge].u=u;e[edge].vis=0;e[edge].next=head[u];head[u]=edge++;
}
bool two_graph(int u,int tim)
{ int v,ret=1;
  for(int i=head[u];~i;i=e[i].next)
  {  v=e[i].v;
    if(!mark[v])continue;
   // printf("%d -> %d ",u,v);
    if(corlor[v]==-1)
    {
      corlor[v]=3-corlor[u];
      ret=two_graph(v,tim);
    }
    else if(corlor[u]==corlor[v])ret=0;
   if(!ret)return 0;
  }
  return ret;
}
void get_corlor(int u,int tim)
{
  memset(mark,0,sizeof(mark));
  int z;
  do
  {
    z=stak[top--];
    mark[e[z].v]=mark[e[z].u]=1;
    //if(e[z].vis!=tim)puts("my god");
   // printf("%d d %d ",e[z].v,e[z].u);
    //puts("");
  }while(e[z].u^u);
  memset(corlor,-1,sizeof(corlor));
  corlor[u]=1;//printf("%d ",u);
  if(!two_graph(u,tim))
  { //puts("yes");
    for(int i=1;i<=n;++i)
      if(mark[i])vis[i]=1;
  }
 // puts("");
}
void get_cut(int u)
{
  dfn[u]=low[u]=++dfs_clock;
  int v=-1;
  for(int i=head[u];~i;i=e[i].next)
  {
    if(e[i].vis)continue;
    v=e[i].v;
    e[i].vis=e[i^1].vis=vis_clock;
    ///printf("%d $ %d\n",u,v);
    stak[++top]=i;
    if(!dfn[v])
    { get_cut(v);
      low[u]=min(low[u],low[v]);
      if(low[v]>=dfn[u])
      { get_corlor(u,vis_clock);
        //puts("");
       ++vis_clock;
      }
    }
    else if(dfn[v]<dfn[u])
    {
      low[u]=min(low[u],dfn[v]);
    }
  }
}

void bcc_find()
{ memset(dfn,0,sizeof(dfn));
  vis_clock=1;top=dfs_clock=0;
  for(int i=1;i<=n;++i)
    if(!dfn[i])
    get_cut(i);
}
int main()
{ int a,b;
  //freopen("data.txt","r",stdin);
  while(~scanf("%d%d",&n,&m))
  { if(n==0&&m==0)break;
    data();
    for(int i=0;i<m;++i)
    {
      scanf("%d%d",&a,&b);g[a][b]=g[b][a]=1;
    }
    //puts("+++++");
    for(int i=1;i<=n;++i)
      for(int j=i+1;j<=n;++j)
      if(!g[i][j])add(i,j),add(j,i)/**,printf("%d %d\n",i,j)*/;
    ///puts("++++");
    memset(vis,0,sizeof(vis));
    bcc_find();
    int ans=n;
    for(int i=1;i<=n;++i)
      if(vis[i])--ans;
    printf("%d\n",ans);
  }
  return 0;
}
/**

*/


离线算法。WA

/**#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
using namespace std;
const int mm=1009;
const int mn=3e6+9;
int head[mm],next[mn],ver[mn],edge;
bool has[mn];
int dfn[mm],low[mm],dfs_clock,bcc_no,n,m;
int p_bcc[mm],corlor[mm];
bool vis[mm],g[mm][mm];
vector<int>bcc[mm];
class node
{
  public:int u,v;
};
stack<int> S;
bool iscut[mm];
void data()
{
  memset(head,-1,sizeof(head));
  memset(corlor,0,sizeof(corlor));
  memset(vis,0,sizeof(vis));
  memset(g,0,sizeof(g));
  memset(has,0,sizeof(has));
  edge=0;
}
void add(int u,int v)
{
  ver[edge]=v;next[edge]=head[u];head[u]=edge++;
}
int get_cut(int u,int fa)
{
  dfn[u]=low[u]=++dfs_clock;
  int child=0,v=-1;
  for(int i=head[u];~i;i=next[i])
  {
    v=ver[i];
    if(!dfn[v])
    { S.push(v);++child;
      ///未访问
      low[u]=min(low[u],get_cut(v,u));
      //cout<<"kk:"<<u<<" "<<v<<endl;
      //cout<<"nn:"<<dfn[u]<<" "<<low[v]<<endl;
      if(low[v]>=dfn[u])
      {
      iscut[u]=1;++bcc_no;
      //cout<<u<<" "<<v<<endl;
      //cout<<"bcc"<<bcc_no<<endl;
      puts("=====");
      if(u==0)
      { while(1)
        {v=S.top();S.pop();
         if(v==0){S.push(v);break;}
        }
        continue;
      }
      while(1)
      {
        v=S.top();S.pop();
        if(u==v){S.push(v);break;}
        if(p_bcc[v]^bcc_no)
          {///bcc[bcc_no].push_back(e.u);
           p_bcc[v]=bcc_no;
          }
        cout<<p_bcc[v]<<" "<<v<<endl;
          //cout<<"v="<<v<<endl;
      }
      puts("====");
     }
    }
    else if(dfn[v]<dfn[u]&&v!=fa)
    {
      low[u]=min(low[u],dfn[v]);
    }
  }

  if(fa<0&&child==1)iscut[u]=0;///根非割点
  return low[u];
}
bool two_graph(int u,int _bcc)
{ int v;
  for(int i=head[u];~i;i=next[i])
  {  v=ver[i];
    if(v<=0||v>n)continue;///超级源
    if(p_bcc[v]^_bcc)continue;
    if(corlor[v]==corlor[u])return 0;
    corlor[v]=3-corlor[u];
    if(!two_graph(v,_bcc))return 0;
  }
  return 1;
}
void dfs(int x)
{ vis[x]=1;///cout<<x<<" ";
  for(int i=head[x];~i;i=next[i])
  {
    if(!vis[ver[i]])
    dfs(ver[i]);
  }
}
void bcc_find()
{ memset(dfn,0,sizeof(dfn));
  memset(iscut,0,sizeof(iscut));
  memset(p_bcc,0,sizeof(p_bcc));
  bcc_no=dfs_clock=0;
  memset(vis,0,sizeof(vis));
  int ret=0;
  for(int i=1;i<=n;++i)
    if(!vis[i]){++ret;dfs(i);add(0,i),add(i,0);/*printf("%d ll\n",i);*/}
 /// printf("the number is %d \n",ret);
  for(int i=0;i<=n;++i)
    if(!dfn[i])
    get_cut(i,-1);
}
int main()
{ int a,b;
  freopen("data.txt","r",stdin);
  while(~scanf("%d%d",&n,&m))
  { if(n==0&&m==0)break;
    data();
    for(int i=0;i<m;++i)
    {
      scanf("%d%d",&a,&b);g[a][b]=g[b][a]=1;
    }
   // puts("--------------");
    for(int i=1;i<=n;++i)
      for(int j=i+1;j<=n;++j)
      if(!g[i][j])add(i,j),add(j,i)/*,printf("%d %d\n",i,j)*/;
    //puts("+++++++++++++++++");
      bcc_find();
      for(int i=0;i<=n;++i)bcc[i].clear();
      bool flag=0;
      for(int i=1;i<=n;++i)
        { //if(p_bcc[0]==p_bcc[i])flag=1;
          bcc[p_bcc[i]].push_back(i);
        }

    for(int i=0;i<=n;++i)
      cout<<i<<" "<<p_bcc[i]<<endl;
    for(int i=0;i<=n;++i)
      if(iscut[i])cout<<" c "<<i;cout<<endl;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=bcc_no;++i)
    { //if(!flag&&i==bcc_no)continue;
      int z=bcc[i].size();
     /** cout<<i<<" bcc";
      for(int j=0;j<z;++j)
        cout<<" "<<bcc[i][j];puts("");*/
      if(!two_graph(bcc[i][0],i))
        {// printf("%d yes\n",i);
         for(int j=0;j<z;++j)
         {if(p_bcc[bcc[i][j]]==i)
         vis[bcc[i][j]]=1;
         }
        }
    }
    int ans=n;
    for(int i=1;i<=n;++i)
      if(vis[i])--ans;
    printf("%d\n",ans);
  }
  return 0;
}
*/




普元EOS8.3精简版安装指南:从零开始搭建低代码开发环境 本文详细介绍了普元EOS8.3精简版的完整安装流程。从JDK1.8环境准备、MySQL数据库配置与初始化,到核心配置文件修改、服务启动与登录验证,提供了从零开始搭建低代码开发环境的清晰步骤和常见问题排坑指南,帮助开发者快速部署并体验平台核心功能。 阅读详情

相关推荐

异步fifo的UVM验证(最终最终版)

更新了refmdl以及scb

qq_44674008的博客 2988

★【双连通分量】【奇环判定】Knights of the Round Table

Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very su

void* ptr = &OI; 1707

服务器被矿工入侵记录

一次服务器被矿工入驻的处理记录

王瑞的技术专栏 1333

Knights of the Round Table

题目链接 题意: n个人开会,会议人数至少为三且为奇数。有些人相互憎恨,这些人不能邻座。统计有几个人不能参加任意一个会议 输入:n,m。m行包括两个整数k1、k2表示两个人相互憎恨。输入结束标志为n=m=0 输出:无法参加任何会议的人数分析: 对于存在割点的图,割点两侧的人肯定不能在一个会议中(不能构成环)。而对于不存在割点的一个极大子图,显然任意两个点都可以在一个会议中。然

Confidence的专栏 1740

Apache Paimon-实时数据湖

Flink社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合,推出新一代的 Streaming Lakehouse 技术,促进数据在数据湖上真正实时流动起来,并为用户提供实时离线一体化的开发体验。Flink 社区内部孵化了 Flink Table Store (简称 FTS )子项目,一个真正面向 Streaming 以及 Realtime的数据湖存储项目。

m0_57307642的博客 2193

《YOLOv8-seg改进》专栏指导书册 &手把手创新教程

学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研;1)手把手教你如何训练YOLOv8-seg;2)模型创新,提升分割性能;3)独家自研模块助力分割;

会AI的学姐 3813

poj 2942 Knights of the Round Table 圆桌骑士(双连通分量模板题)

Knights of the Round Table Time Limit:7000MS Memory Limit:65536K Total Submissions:9169 Accepted:2960 Description Being a knight is a very attractive ca...

weixin_30633949的博客 210

Qt/C++ 音视频开发 - FFmpeg 安卓版

通过将 FFmpeg 集成到 Qt/C++ 项目中,我们可以实现强大且灵活的音视频处理功能。本文介绍了在安卓平台上使用 FFmpeg 的基本步骤,包括初始化、解码、处理和编码等。实际应用代码示例展示了如何在安卓设备上播放视频。

走向CTO的路上... 1192

[UVA1364] [POJ2942] Knights of the Round Table

POJ传送门 Luogu传送门 UVA传送门 题意翻译 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1、 相互憎恨的两个骑士不能坐在直接相邻的2个位置; 2、 出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果。 如果出现有某些骑士无法出席所有会议(例如这个骑士憎恨所有的其他骑士),则亚...

LPA的博客 291

芯擎SEC1000芯片参数详细介绍

随着龙鹰一号的不断进化和应用,未来的智能座舱将不仅仅是显示和控制的集成,更是人与车之间的一种默契和无缝交互的体现。在汽车行业迈向智能化和电动化的浪潮中,座舱已不仅仅是一个驾驶者的操作空间,而是逐渐演变为一个集娱乐、信息、控制于一体的智能交互平台。今天的汽车不仅需要强劲的动力和炫酷的外观,更需要一颗强大而智能的“心脏”来支撑复杂的座舱体验和安全驾驶需求。想象一下,未来的汽车不再仅仅是交通工具,它将成为你的移动私人管家,了解你的习惯,甚至提前预测你的需求。让我们一起走进龙鹰一号的世界,探索智能座舱的无限可能!

weixin_43199439的博客 1725

Python经典编程习题100例:第25例:求各个阶乘的和

不要自卑,去提升实力 互联网行业谁技术牛谁是爹 如果文章可以带给你能量,那是最好的事!请相信自己 加油o~ 本人初学Python,只为熟悉语法编写,大神请勿理会 点击下面链接 Python经典编程100例习题汇总 题目描述: 求1+2!+3!+…+20!的和。 解题思路: > 调用math模块中的factorial函数 代码: import math sum=0 for i in range(1,21): sum+=math.factorial(i) print(sum) ..

优快云 精品推荐 2736

UVa 1364 Knights of the Round Table

摘要 题目描述亚瑟王国骑士圆桌会议的组织问题。由于骑士数量增加和饮酒后的冲突风险,梅林制定了两个规则:互相憎恨的骑士不能相邻而坐,且参与骑士数必须为奇数。需要计算必须开除的骑士数量。算法将问题转化为在补图中寻找奇环,使用Tarjan算法找点双连通分量,并通过二分图检测判断是否存在奇环。不属于任何奇环的顶点对应骑士将被开除。最终统计未被标记的顶点数量即为答案。

寂静山林 572

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

UVa1364/LA3523 Knights of the Round Table

每次圆桌会议至少应有3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置。如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防止赞同和反对票一样多。将不相互憎恨的骑士连一条无向边建图,如果对一个结点(骑士)能找到含奇数个结点且结点不重复的圈,则此骑士至少可以参加一个会议。,所以只需要关注那些不是二分图的双连通分量。更进一步,如果一个双连通分量不是二分图,它至少含有一个长度为奇数的环。中所有结点标记为“在长度为奇数的环上”,最后遍历每个结点,统计出无标记的结点数就是答案。

hlhgzx的博客 1068

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

UVA1364 Knights of the Round Table

双联通、图论

ACoder 180

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

UVA1364 Knights of the Round Table(双连通分量、二分图染色,超详细解释)

UVA1364 Knights of the Round Table #include<cstdio> #include<cmath> #include<algorithm> #include<iostream> #include<cstring> #include<vector> using namespace std; typedef long long ll; const int N = 5007, M = 500007, IN

繁凡さん的博客 482

POJ2942 UVA1364 Knights of the Round Table 圆桌骑士

POJ2942洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则题意变为求图中不在任何奇环(结点数为奇数的环)中的点的数量。 一个环上的点一定属于一个双连通分量(两两都有两条路径可达) 那么什么时候双连通分量中没有奇环呢? 显然,当双连通分...

baben4194的博客 214

UVA 1364 - Knights of the Round Table(双连通+二分图判定)

UVA 1364 - Knights of the Round Table 题目链接 题意:有n个圆桌骑士,知道一些骑士互相憎恨,现在要开圆桌会议,每次最少3个人,必须是奇数人数,并且互相憎恨的骑士不能在相邻,问有多少骑士是一次都无法参加的 思路:把每个骑士可以相邻的连边,然后做双连通分量,然后对于每个连通分量,利用二分图染色判定去判断是否是奇圈 代码: #inclu

Remilia's 1014

[UVA1364 | POJ | NC]Knights of the Round Table | Tarjan 求点双 | 二分图 | 综合图论

评测地址: 网址1 网址2 题目描述: 题意: 给出n位骑士,然后有m个关系,每个关系以格式: a ba\ ba b给出,表达骑士aaa不能和bbb相邻,问要想使得最多的奇数个骑士在一起围成一圈,要剔除多少人 solution: 一. part1 : 首先解决这道题要用到的知识点: 1. 建立补图 2. Tarjan求解点双连通分量(V-DCC)并记录 3. 奇环 4. 二分图的判定(二分图染色) 二. part2 概念解析: 所谓补图,就是将原图中连着的边去掉,而将原来没有连的边

PushyTao的博客 304

Knights of the Round Table UVA - 1364(tarjan 无向图 点-双连通分量&&思维)建图+点双+dfs染色

Knights of the Round Table UVA - 1364 题意: 有n个圆桌骑士。给你m个互相憎恶的关系。 相互憎恶的骑士不可以坐在一起,且围起来的圈必须是奇数圈。 思路(本题细节比较多): 首先a和b相互憎恶,那么我们可以抽象成图,a和b之间没有边(那么现在把 不互相憎恶的骑士 连起来) 之后就有了一个图。题目就转换成了求不在任何一个简单奇圈上的结点数。如果图G不连通,应该对每个连通分量分别求解。 结论:(证明过程在后面) 可以证明在一个双连通分量里,假如B不是二分图,那么它含有奇圈,

qq_45377553的博客 137

UVA 1364 - Knights of the Round Table (找双连通分量 + 二分图染色法判断)

亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突, 并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1、 相互憎恨的两个骑士不能坐在直接相邻的2个位置; 2、 出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果。

GejinZ 916

UVA 1364 Knights of the Round Table(双联通+二分图)

先把所有的双联通找出来,然后对每个双联通进行二分图判断,因为双联通分量是联通的,并且二分图肯定是偶数个点,那么如果一个双联通并且他不是二分图,那么他是不符合条件的,所以减去。#include #include #include #include #include #include using namespace std; const int maxn=1000+5; int color[maxn]

qq_33901573的博客 278
上一篇: hdu 4346 The Beautiful Road(思维,枚举,5级)
下一篇: windows 开发之hello world
剑不飞
博客等级 码龄15年 86粉丝 505原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值