标签:两个 int wh Ronald read 集合 操作
首先从简单的问题开始思考。假如我们只有两个点,应该如何构造方案呢?显然,当两个点有连边时,我们不需要做任何事情(当然两个点各操作一次也是可以的但没有必要);而两个点没有连边时,只需要选择其中任意一个进行一次操作即可。从这里得出了一个重要的结论,由于操作同一个点两次之后会导致某些对点的连接状态变过去再变回来,相当于没有操作,所以一个点的操作次数要么是零次,要么是零次。
推而广之,对于任意的两个点,要让最后有边连接这两个点,也需要分类讨论。假如一开始这两个点有边,那么要么两个点都不操作,要么两个点都操作一次;假如一开始两个点没有边,那么这两个点中应该只有一个操作过一次,另一个没有操作。然后可以抽离出模型来,可以把操作一次的点放在一个集合,没操作的放在另一个集合;两个点一开始没有连边的话代表这两个点不在同一集合,否则说明在一个集合,根据这个关系判断是不是二分图即可(一个点只能属于一个集合对吧)。
具体实现不用那么麻烦,由于一开始第一个点和其它所有点的连边情况是已知的,所以可以强制一号点属于某个集合,这样一来所有点的集合归属就已经确定了,然后扫描后面的点看有没有矛盾就可以了。
#include<bits/stdc++.h>
//#define feyn
using namespace std;
const int N=1010;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,n;
bool e[N][N],a[N];
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);read(n);int s1,s2;
while(n--){
read(s1);read(s2);
e[s1][s2]=e[s2][s1]=true;
}
for(int i=2;i<=m;i++)a[i]=e[1][i];
for(int i=2;i<m;i++){
for(int j=i+1;j<=m;j++){
if(e[i][j]==true&&a[i]!=a[j]){
printf("NE\n");return 0;
}
if(e[i][j]==false&&a[i]==a[j]){
printf("NE\n");return 0;
}
}
}
printf("DA\n");
return 0;
}
标签:两个,int,wh,Ronald,read,集合,操作 来源: https://www.cnblogs.com/dai-se-can-tian/p/16534585.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。